Announcement Announcement Module
Collapse
No announcement yet.
Problems with Spring Transaction Support Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problems with Spring Transaction Support

    Hello,

    I'll try to explain the problem as clear as possible.

    I have a web app with Hibernate on persistence layer.

    I have a service class called UserServiceImpl with a dependency to a DAO object. In my service class, there is a method called updatePrefixes() that invokes two methods on DAO object: a method removeAll(Object) and another one to insertAll(Object).

    Code:
        public void updatePrefixes(User user) {
            List prefixes = getUserDAO().findPrefixesFrom(user);
     
            if(prefixes!=null && !prefixes.isEmpty()){
                // execute remove first
                removeAll(prefixes);
            }
     
            getUserDAO().deletePrefixesFrom(user);
            removeUnwantedPrefixes(user);
     
            if(user.getPrefixes()!=null){
                // execute insert last
                insertAll(user.getPrefixes());
            }
     
        }

    These methods are called in the followin order:
    dao.removeAll();
    dao.insertAll();

    I've declared the service's methods to be managed by Spring Transaction in the applicationContext.xml:

    Code:
     
    <beans>
    ...
      <!-- Transaction manager for a single Hibernate SessionFactory &#40;alternative to JTA&#41; -->
      <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
        <property name="sessionFactory">
          <ref bean="sessionFactory"/>
        </property>
      </bean>
     
      <!-- Transaction Interceptor set up to do PROPAGATION_REQUIRED on all methods -->
      <bean id="matchAllWithPropReq" class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource">
        <property name="transactionAttribute"><value>PROPAGATION_REQUIRED</value></property>
      </bean>
      <bean id="matchAllTxInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager"><ref bean="transactionManager"/></property>
        <property name="transactionAttributeSource"><ref bean="matchAllWithPropReq"/></property>
      </bean>
     
      <!-- One BeanNameAutoProxyCreator handles all beans where we want all methods to use PROPAGATION_REQUIRED -->
      <bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="interceptorNames">
          <list>
            <idref local="matchAllTxInterceptor"/>
          </list>
        </property>
        <property name="beanNames">
          <list>
            <idref local="callService"/>
            <idref local="logService"/>
            <idref local="userService"/>
            <idref local="accountService"/>
          </list>
        </property>
      </bean>
     
    </beans>
    The PROPAGATION_REQUIRED transaction definition means that the DAO's methods will execute in the service's method transaction.

    The problems is that the DAO's removeAll() method is called after the insertAll() method.

    How can I do to execute the DAO's mehtods in the order that they were declared?

    Thanks a lot.

    Regis Santos

  • #2
    Spring will not change your code, such as reordering method invocations. So perhaps the issue is the conditionals not firing as you expect.

    Have you tried a debugger?

    Rgds
    Rod

    Comment


    • #3
      Hello Rod,

      Yes, I have. I think that the problem is the Hibernate. When I invoke the dao.removeAll() method, it doesn't execute the SQL DELETE operation at that time. It waits until the service's method has finished.

      Then, it executes the SQL INSERT at first and the SQL DELETE at last.

      Do you have any idea?

      Regis Santos

      Comment


      • #4
        Have you tried a manual flush of the hibernate session (after the deletes and before the mass inserts)?

        Comment


        • #5
          Hello,

          Please, see the log below.

          Code:
          DEBUG net.sf.hibernate.impl.SessionImpl - 1 collections were found in result set
          DEBUG net.sf.hibernate.impl.SessionImpl - collection fully initialized&#58; ...
          DEBUG net.sf.hibernate.impl.SessionImpl - 1 collections initialized
          DEBUG net.sf.hibernate.impl.SessionImpl - collection initialized
          DEBUG org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value ...
          ...
          DEBUG net.sf.hibernate.impl.SessionImpl - deleting a persistent instance
          ...
          DEBUG net.sf.hibernate.impl.SessionImpl - deleting a persistent instance
          ...
          DEBUG net.sf.hibernate.impl.SessionImpl - deleting a persistent instance
          ...
          DEBUG net.sf.hibernate.impl.SessionImpl - generated identifier&#58; ...
          DEBUG net.sf.hibernate.impl.SessionImpl - saving ...
          ...
          DEBUG net.sf.hibernate.impl.SessionImpl - generated identifier&#58; ...
          DEBUG net.sf.hibernate.impl.SessionImpl - saving ...
          ...
          DEBUG net.sf.hibernate.impl.SessionImpl - generated identifier&#58; ...
          ...
          DEBUG org.springframework.transaction.interceptor.TransactionInterceptor - Invoking commit for transaction on method 'updatePrefixes' in class &#91;br.com.ivia.ddd.service.UserService&#93;
          DEBUG org.springframework.orm.hibernate.HibernateTransactionManager - Triggering beforeCommit synchronization
          DEBUG org.springframework.orm.hibernate.HibernateTransactionManager - Triggering beforeCompletion synchronization
          DEBUG org.springframework.orm.hibernate.HibernateTransactionManager - Initiating transaction commit
          DEBUG org.springframework.orm.hibernate.HibernateTransactionManager - Committing Hibernate transaction on session...
          DEBUG net.sf.hibernate.transaction.JDBCTransaction - commit
          DEBUG net.sf.hibernate.impl.SessionImpl - flushing session
          DEBUG net.sf.hibernate.impl.SessionImpl - Collection dirty&#58; &#91;br.com.ivia.ddd.model.User.prefixes#125&#93;
          DEBUG net.sf.hibernate.impl.SessionImpl - Flushing entities and processing referenced collections
          DEBUG net.sf.hibernate.impl.SessionImpl - Collection found&#58; &#91;br.com.ivia.ddd.model.User.phones#125&#93;, was&#58; &#91;br.com.ivia.ddd.model.User.phones#125&#93;
          DEBUG net.sf.hibernate.impl.SessionImpl - Collection found&#58; &#91;br.com.ivia.ddd.model.User.prefixes#125&#93;, was&#58; &#91;br.com.ivia.ddd.model.User.prefixes#125&#93;
          DEBUG net.sf.hibernate.impl.SessionImpl - Processing unreferenced collections
          DEBUG net.sf.hibernate.impl.SessionImpl - Scheduling collection removes/&#40;re&#41;creates/updates
          DEBUG net.sf.hibernate.impl.SessionImpl - Flushed&#58; 3 insertions, 0 updates, 3 deletions to 11 objects
          DEBUG net.sf.hibernate.impl.SessionImpl - Flushed&#58; 0 &#40;re&#41;creations, 1 updates, 0 removals to 2 collections
          DEBUG net.sf.hibernate.impl.Printer - listing entities&#58;
          ...
          DEBUG net.sf.hibernate.impl.SessionImpl - executing flush
          DEBUG net.sf.hibernate.persister.EntityPersister - Inserting entity&#58; ...
          DEBUG net.sf.hibernate.impl.BatcherImpl - about to open&#58; 0 open PreparedStatements, 0 open ResultSets
          DEBUG net.sf.hibernate.SQL - insert into T_PREFIXES &#40;CD_AREA, ID_USER, NR_NUMBER&#41; values &#40;?, ?, ?&#41;
          ...
          DEBUG net.sf.hibernate.impl.BatcherImpl - preparing statement
          DEBUG net.sf.hibernate.persister.EntityPersister - Dehydrating entity&#58; ...
          ...
          DEBUG net.sf.hibernate.persister.EntityPersister - Inserting entity&#58; ...
          DEBUG net.sf.hibernate.impl.BatcherImpl - reusing prepared statement
          DEBUG net.sf.hibernate.SQL - insert into T_PREFIXES &#40;CD_AREA, ID_USER, NR_NUMBER&#41; values &#40;?, ?, ?&#41;
          ...
          DEBUG net.sf.hibernate.persister.EntityPersister - Dehydrating entity&#58; ...
          ...
          DEBUG net.sf.hibernate.SQL - insert into T_PREFIXES &#40;CD_AREA, ID_USER, NR_NUMBER&#41; values &#40;?, ?, ?&#41;
          ...
          DEBUG net.sf.hibernate.persister.EntityPersister - Dehydrating entity&#58; ...
          ...
          DEBUG net.sf.hibernate.util.JDBCExceptionReporter - SQL Exception
          java.sql.BatchUpdateException&#58; ORA-00001&#58; unique constraint &#40;DDD.PK_T_PREFIXES&#41; violated
          ...
          DEBUG org.springframework.orm.hibernate.HibernateTransactionManager - Rolling back Hibernate transaction on session...
          DEBUG net.sf.hibernate.transaction.JDBCTransaction - rollback
          DEBUG net.sf.hibernate.impl.SessionImpl - transaction completion
          DEBUG net.sf.hibernate.transaction.JDBCTransaction - re-enabling autocommit

          Thanks for help.

          Comment


          • #6
            Can you post the code around the deleteAll insertAll stuff? Manual flush didn't helped?

            Comment


            • #7
              Hello Martin,

              The manual flush worked.

              I tried another way that worked too. I iterated through the collection and invoked the remove() method for each item.

              Thanks a lot.

              Comment

              Working...
              X