Announcement Announcement Module
Collapse
No announcement yet.
Changes to persistent object not flushed Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Changes to persistent object not flushed

    Hi

    Are objects returned from a Hibernate criteria list() persistent? I've got a method fetching a list of objects, then setting an association to each intance. This method is transactional, so I'd expect those objects to be updated on exit. But nothing happens.

    Code:
    public BookingModel settleCharges() throws Exception {
    		// get existing, open charges from the database
    		List<BookingModel> opencharges = dao.getOpenUspCharges();
    		BookingModel settlement = new BookingModel();
    		double totalcharge = 0;
    
    		for (BookingModel charge : opencharges) {
    			charge.setReferencebooking(settlement);
    			settlement.getChildBookings().add(charge);
    			
    			totalcharge += charge.getAmount();
    		}
    		
    		settlement.setAmount(totalcharge);
    		settlement.setCreatedate(new Date());
    		
    		dao.save(settlement);
    }
    Code:
    <bean id="bookingService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="transactionManager"/>
    		<property name="target" ref="bookingServiceTarget"/>
    		<property name="transactionAttributes">
    		<props>
    			<prop key="save*">PROPAGATION_REQUIRED</prop>
    			<prop key="settleCharges*">PROPAGATION_REQUIRED</prop>
    			<prop key="load*">PROPAGATION_SUPPORTS</prop>
    			<prop key="search*">PROPAGATION_SUPPORTS</prop>
    			<prop key="*">PROPAGATION_SUPPORTS</prop>
    		</props>
    		</property>
    	</bean>
    Code:
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 20.07.2006 10:30:14 by Hibernate Tools 3.1.0.beta5 -->
    <hibernate-mapping>
        <class name="net.umbrella.data.model.BookingModel" table="BOOKINGS">
            <id name="id" type="int">
                <column name="ID" />
                <generator class="native" />
            </id>
            <version column="LASTMODIFIED" name="lastmodified" type="timestamp" />
            <many-to-one name="clients" class="net.umbrella.data.model.ClientModel" fetch="select">
                <column name="CLIENTID" not-null="true" />
            </many-to-one>
            <many-to-one name="branches" class="net.umbrella.data.model.BranchModel" fetch="select">
                <column name="BRANCHID" />
            </many-to-one>
            <many-to-one name="users" class="net.umbrella.data.model.UserModel" fetch="select">
                <column name="USERID" />
            </many-to-one>
            <many-to-one name="referencebooking" class="net.umbrella.data.model.BookingModel" fetch="select">
                <column name="BOOKINGID" />
            </many-to-one>
            <many-to-one name="orders" class="net.umbrella.data.model.OrderModel" fetch="select">
                <column name="ORDERID" />
            </many-to-one>
            <many-to-one name="customers" class="net.umbrella.data.model.CustomerModel" fetch="select">
                <column name="CUSTOMERID" />
            </many-to-one>
            <many-to-one name="customerroles" class="net.umbrella.data.model.CustomerroleModel" fetch="select">
                <column name="CUSTOMERROLEID" />
            </many-to-one>
            <many-to-one name="accountsByCreditaccount" class="net.umbrella.data.model.AccountModel" fetch="select">
                <column name="CREDITACCOUNTID" not-null="true" />
            </many-to-one>
            <many-to-one name="accountsByDebitaccount" class="net.umbrella.data.model.AccountModel" fetch="select">
                <column name="DEBITACCOUNTID" not-null="true" />
            </many-to-one>                
            <many-to-one name="besr" class="net.umbrella.data.model.BesrModel" fetch="select" cascade="all">
                <column name="BESRID" />
            </many-to-one>
            <many-to-one name="documenthistory" class="net.umbrella.data.model.DocumenthistoryModel" fetch="select" cascade="all">
                <column name="DOCUMENTHISTORYID" />
            </many-to-one>
            <property name="number" type="string">
                <column name="NUMBER" length="50" />
            </property>
            <property name="text" type="string">
                <column name="TEXT" />
            </property>
            <property name="remark" type="text">
                <column name="REMARK" />
            </property>
            <property name="amount" type="java.lang.Double">
                <column name="AMOUNT" scale="4" />
            </property>
            <property name="paymentdate" type="timestamp">
                <column name="PAYMENTDATE" length="23" />
            </property>
            <property name="createdate" type="timestamp">
                <column name="CREATEDATE" length="23" />
            </property>
            <property name="ccnameoncc" type="string">
                <column name="CCNAMEONCC" />
            </property>
            <property name="ccnumber" type="string">
                <column name="CCNUMBER" length="50" />
            </property>
            <property name="ccexpiration" type="timestamp">
                <column name="CCEXPIRATION" length="23" />
            </property>
            <property name="lastmodifiedby" type="string">
                <column name="LASTMODIFIEDBY" length="100" />
            </property>
            <set name="paymentInvoiceMaps" inverse="true">
                <key>
                    <column name="PAYMENTID" not-null="true" />
                </key>
                <one-to-many class="net.umbrella.data.model.PaymentInvoiceMapModel" />
            </set>
            <set name="childBookings" inverse="true" cascade="persist,save-update">
                <key column="BOOKINGID" />
                <one-to-many class="net.umbrella.data.model.BookingModel" />
            </set>
            
        </class>
    </hibernate-mapping>
    On exiting the settleCharges() method, the newly created BookingModel instance is inserted into the database, but the (composite) references are not updated.

    Is there a Hibernate bug preventing a persistence class to have an association onto itself?

    I've got plenty of working examples and just can't find why this one is NOT. Even hints on what I should look into are welcome, getting desparate here.

    Thanks
    Simon

  • #2
    The changes to the 'charges' are not flushed! When I flush the Hibernate session manually within the settleCharges(), all BookingModel instances get updated.

    It seems my transaction rule for settleCharges* is not activated correctly. Interestingly, my unit test (using AbstractTransactionalSpringContextTests) now runs (i.e. UPDATEs are executed), but when I execute the exact same code from the running web application, the UPDATEs are NOT executed.

    Still pretty much in the dark here.

    Cheers
    Simon

    Comment


    • #3
      Might the OpenSessionInView filter be the culprit here?

      Comment


      • #4
        Originally posted by sniederb View Post
        Might the OpenSessionInView filter be the culprit here?
        It could be. Are you referencing bookingService or bookingServiceTarget from the other beans? It needs to be the former. It would be useful to see the log output and also the rest of the XML.

        Comment


        • #5
          hi karl

          good to hear from you again! OpenSessionInView definitely affects the problem, setting singleSession to false would solve the problem, but introduce quite a few other ones.

          Based on that, I disabled all controller code called previous to the settleCharges() call, and then everything works. So a previous call alters the Hibernate session such that changes are not flushed.

          If I first run a load on a user

          Code:
          <bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          		<property name="transactionManager" ref="transactionManager"/>
          		<property name="target" ref="userServiceTarget"/>
          		<property name="transactionAttributes">
          		<props>
          			<prop key="increaseLoginFailureCount">PROPAGATION_REQUIRED</prop>
          			<prop key="trackSuccessfulLogin">PROPAGATION_REQUIRED</prop>
          			<prop key="save*">PROPAGATION_REQUIRED</prop>
          			<prop key="load*">PROPAGATION_SUPPORTS</prop>
          			<prop key="search*">PROPAGATION_SUPPORTS</prop>
          			<prop key="*">PROPAGATION_SUPPORTS</prop>
          		</props>
          		</property>
          	</bean>
          and then run settleCharges(), does that PROPAGATION_SUPPORTS from the user#load somehow affect the following call?

          Cheers
          Simon

          Comment


          • #6
            Oh, I forgot, I'm referencing the bookingService, not the target. Transactions are active, I've checked that.

            Comment


            • #7
              Prior to the settleCharges() call, I'm running a JasperReport which gives me a PDF byte-array, which I then pass into the settleCharges(). From the log I find that the BookingModel instancens I load during settleCharges() are already in the session due to the report.

              So now I'm thinking: does JasperReports somehow load those entities read-only, so any changes I then make are discarded on closing the session?

              Simon

              Comment


              • #8
                Yup, there we have it. JasperReports has already loaded those BookingModels into the session. If I call a session.clear() prior to my settleCharges(), the BookingModel entities get reloaded, and the UPDATEs are indeed executed.

                I'll be looking into how to best fix this, but the cause has been identified.

                Cheers
                Simon

                Comment

                Working...
                X