Announcement Announcement Module
Collapse
No announcement yet.
Hibernate Session Per Request Problem with CMT EJB Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate Session Per Request Problem with CMT EJB

    I was running some tests and noticed that when my I access my DAOs from a WebLogic 8.1 SP3 CMT Stateless EJB...sessions are not being treated in a session-per-transaction manner...every call to my DAO gets a new session, and then closes it (session-per-request).

    Interestingly enough, when I run this outside of the container and begin/commit my own transaction...I do get session-per-transaction.

    I am using Spring's (1.1.1) Hibernate (2.1.6) DAO Support and wrapping my DAOs in a transaction proxy factory bean.

    Below is my config and test class:

    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryB ean">
    <property name="jndiName"><value>SLDB_DS</value></property>
    </bean>

    <!-- Hibernate Session Factory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSess ionFactoryBean">
    <property name="dataSource"><ref bean="dataSource"/></property>
    <property name="mappingResources">
    <list>
    <value>com/level3/sldb/framework/dao/dto/PropertyDTO.hbm.xml</value>
    </list>
    </property>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">net.sf.hibernate.dialect.O racle9Dialect</prop>
    </props>
    </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTran sactionManager"/>

    <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean"
    abstract="true">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="transactionAttributes">
    <props>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="store*">PROPAGATION_REQUIRED</prop>
    <prop key="delete*">PROPAGATION_REQUIRED</prop>
    </props>
    </property>
    </bean>

    <bean id="com.level3.sldb.framework.dao.DAOCommonIF" parent="baseTransactionProxy">
    <property name="target">
    <bean class="com.level3.sldb.framework.dao.DAOCommon">
    <property name="sessionFactory"><ref local="sessionFactory"/></property>
    </bean>
    </property>
    </bean>

    DAO Class:


    Code:
    public class DAOCommon extends HibernateDaoSupport implements DAOCommonIF &#123;
    
      public PropertyDTO loadProperty&#40;Long id&#41; throws DataAccessException &#123;
        return &#40;PropertyDTO&#41; getHibernateTemplate&#40;&#41;.load&#40;PropertyDTO.class, id&#41;;
      &#125;
      public void storeProperty&#40;PropertyDTO property&#41; throws DataAccessException &#123;
        getHibernateTemplate&#40;&#41;.saveOrUpdate&#40;property&#41;;
      &#125;
    Example Code in EJB:
    Code:
    	
    public Class SomeEJB extends StatelessSessionBean... 
    	try &#123;
    			ClassFactoryIF cf = new ClassFactory&#40;&#41;;
    			DAOCommonIF dao = &#40;DAOCommonIF&#41; cf.getObject&#40;DAOCommonIF.class&#41;;
    			PropertyDTO p = new PropertyDTO&#40;&#41;;
    			logger.log&#40;Priority.WARN, "STORING PROPERTY"&#41;;
    			dao.storeProperty&#40;p&#41;;
    			logger.log&#40;Priority.WARN, "STORED PROPERTY"&#41;;
    			logger.log&#40;Priority.WARN, "DELETING PROPERTY"&#41;;
    			dao.deleteProperty&#40;p&#41;;
    			logger.log&#40;Priority.WARN, "DELETED PROPERTY"&#41;;
    Proof that the session is NOT being reused per dao call:

    vo,83 ] : STORING PROPERTY
    transaction,195 ] : Using transaction object [org.springframework.transaction.jta.JtaTransaction Object@21eb8a7]
    transaction,248 ] : Participating in existing transaction
    ansactionSynchronizationManager,194 ] : Initializing transaction synchronization
    hibernate,329 ] : Opening Hibernate session
    hibernate,555 ] : opened session
    hibernate,340 ] : Registering Spring transaction synchronization for new Hibernate session
    lang,142 ] : Bound value [org.springframework.orm.hibernate.SessionHolder@22 4c75b] for key [net.sf.hibernate.impl.SessionFactoryImpl@29185be] to thread [ExecuteThread: '21' for queue: 'weblogic.kernel.Default']
    lang,1387 ] : saveOrUpdate() unsaved instance
    io,825 ] : saving [com.level3.sldb.framework.dao.dto.PropertyDTO#511]
    lang,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@22 4c75b] for key [net.sf.hibernate.impl.SessionFactoryImpl@29185be] bound to thread [ExecuteThread: '21' for queue: 'weblogic.kernel.Default']
    interceptor,240 ] : Invoking commit for transaction on method 'storeProperty' in class [com.level3.sldb.framework.dao.DAOCommonIF]
    support,495 ] : Triggering beforeCommit synchronization
    SessionFactoryUtils$SpringSessionSynchronization,6 47 ] : Flushing Hibernate session on transaction synchronization
    SessionImpl,2246 ] : flushing session
    SessionImpl,2439 ] : Flushing entities and processing referenced collections
    SessionImpl,2780 ] : Processing unreferenced collections
    SessionImpl,2270 ] : Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects
    SessionImpl,2275 ] : Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
    SessionImpl,2359 ] : executing flush
    engine,453 ] : Inserting entity: [com.level3.sldb.framework.dao.dto.PropertyDTO#511]
    BatcherImpl,200 ] : about to open: 0 open PreparedStatements, 0 open ResultSets
    lang,226 ] : insert into PROPERTIES (NAME, VALUE, DESCRIPTION, LAST_UPDATED, LAST_UPDATED_USER, PROPERTY_ID) values (?, ?, ?, ?, ?, ?)
    sql,249 ] : preparing statement
    engine,388 ] : Dehydrating entity: [com.level3.sldb.framework.dao.dto.PropertyDTO#511]
    BatcherImpl,207 ] : done closing: 0 open PreparedStatements, 0 open ResultSets
    sql,269 ] : closing statement
    SessionImpl,2824 ] : post flush
    lang,510 ] : Triggering beforeCompletion synchronization
    lang,165 ] : Removed value [org.springframework.orm.hibernate.SessionHolder@22 4c75b] for key [net.sf.hibernate.impl.SessionFactoryImpl@29185be] from thread [ExecuteThread: '21' for queue: 'weblogic.kernel.Default']
    lang,540 ] : Triggering afterCompletion synchronization
    SessionImpl,585 ] : transaction completion
    hibernate,572 ] : Closing Hibernate session
    sql,573 ] : closing session
    sql,3336 ] : disconnecting session
    SessionImpl,585 ] : transaction completion
    TransactionSynchronizationManager,234 ] : Clearing transaction synchronization
    vo,85 ] : STORED PROPERTY
    vo,86 ] : DELETING PROPERTY
    interceptor,197 ] : Getting transaction for method 'deleteProperty' in class [com.level3.sldb.framework.dao.DAOCommonIF]
    transaction,195 ] : Using transaction object [org.springframework.transaction.jta.JtaTransaction Object@227ae8c]
    transaction,248 ] : Participating in existing transaction
    TransactionSynchronizationManager,194 ] : Initializing transaction synchronization
    hibernate,329 ] : Opening Hibernate session
    hibernate,555 ] : opened session
    hibernate,340 ] : Registering Spring transaction synchronization for new Hibernate session
    lang,142 ] : Bound value [org.springframework.orm.hibernate.SessionHolder@23 77375] for key [net.sf.hibernate.impl.SessionFactoryImpl@29185be] to thread [ExecuteThread: '21' for queue: 'weblogic.kernel.Default']
    lang,1132 ] : deleting a transient instance
    persister,1179 ] : deleting [com.level3.sldb.framework.dao.dto.PropertyDTO#511]
    lang,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@23 77375] for key [net.sf.hibernate.impl.SessionFactoryImpl@29185be] bound to thread [ExecuteThread: '21' for queue: 'weblogic.kernel.Default']
    interceptor,240 ] : Invoking commit for transaction on method 'deleteProperty' in class [com.level3.sldb.framework.dao.DAOCommonIF]
    support,495 ] : Triggering beforeCommit synchronization
    SessionFactoryUtils$SpringSessionSynchronization,6 47 ] : Flushing Hibernate session on transaction synchronization
    SessionImpl,2246 ] : flushing session
    SessionImpl,2439 ] : Flushing entities and processing referenced collections
    SessionImpl,2780 ] : Processing unreferenced collections
    SessionImpl,2794 ] : Scheduling collection removes/(re)creates/updates
    SessionImpl,2270 ] : Flushed: 0 insertions, 0 updates, 1 deletions to 1 objects
    SessionImpl,2275 ] : Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
    util,75 ] : listing entities:
    util,82 ] : com.level3.sldb.framework.dao.dto.PropertyDTO{valu e=mybeanvalue, lastUpdatedUser=null, description=null, lastUpdated=null, name=mybeantest, propertyId=511}
    SessionImpl,2359 ] : executing flush
    engine,570 ] : Deleting entity: [com.level3.sldb.framework.dao.dto.PropertyDTO#511]
    BatcherImpl,200 ] : about to open: 0 open PreparedStatements, 0 open ResultSets
    lang,226 ] : delete from PROPERTIES where PROPERTY_ID=?
    sql,249 ] : preparing statement
    lang,46 ] : binding '511' to parameter: 1
    BatchingBatcher,28 ] : Adding to batch
    sql,50 ] : Executing batch size: 1
    sql,58 ] : success of batch update unknown: 0
    BatcherImpl,207 ] : done closing: 0 open PreparedStatements, 0 open ResultSets
    sql,269 ] : closing statement
    SessionImpl,2824 ] : post flush
    lang,510 ] : Triggering beforeCompletion synchronization
    lang,165 ] : Removed value [org.springframework.orm.hibernate.SessionHolder@23 77375] for key [net.sf.hibernate.impl.SessionFactoryImpl@29185be] from thread [ExecuteThread: '21' for queue: 'weblogic.kernel.Default']
    lang,540 ] : Triggering afterCompletion synchronization
    SessionImpl,585 ] : transaction completion
    hibernate,572 ] : Closing Hibernate session
    sql,573 ] : closing session
    sql,3336 ] : disconnecting session
    SessionImpl,585 ] : transaction completion
    TransactionSynchronizationManager,234 ] : Clearing transaction synchronization
    vo,88 ] : DELETED PROPERTY



    Example out of container Code that works when I begin/commit Tx:

    Code:
    		TransactionStatus status = tm.getTransaction&#40;def&#41;;
    		PropertyDTO p = getTestProperty&#40;&#41;;
    		daoImpl.storeProperty&#40;p&#41;;
    		PropertyDTO pTest = daoImpl.loadProperty&#40;p.getPropertyId&#40;&#41;&#41;;
    		assertEquals&#40;name, pTest.getName&#40;&#41;&#41;;
    		assertEquals&#40;value, pTest.getValue&#40;&#41;&#41;;
    		daoImpl.deleteProperty&#40;pTest&#41;;
    		tm.commit&#40;status&#41;;
    Proof that the session IS being re-used out of container:

    [AbstractPlatformTransactionManager,195 ] : Using transaction object [org.springframework.orm.hibernate.HibernateTransac tionObject@293b53]
    [AbstractPlatformTransactionManager,267 ] : Creating new transaction
    [ SessionFactoryUtils,329 ] : Opening Hibernate session
    [ SessionImpl,555 ] : opened session
    [HibernateTransactionManager,370 ] : Opened new session [net.sf.hibernate.impl.SessionImpl@48ff68] for Hibernate transaction
    [SingleConnectionDataSource,164 ] : Returning single connection: oracle.jdbc.driver.OracleConnection@566633
    [ JDBCTransaction,37 ] : begin
    [ JDBCTransaction,41 ] : current autocommit status:true
    [ JDBCTransaction,43 ] : disabling autocommit
    [HibernateTransactionManager,412 ] : Exposing Hibernate transaction as JDBC transaction [oracle.jdbc.driver.OracleConnection@566633]
    [TransactionSynchronizationManager,142 ] : Bound value [org.springframework.jdbc.datasource.ConnectionHold er@194adaa] for key [org.springframework.jdbc.datasource.SingleConnecti onDataSource@16b69d7] to thread [main]
    [TransactionSynchronizationManager,142 ] : Bound value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] to thread [main]
    [TransactionSynchronizationManager,194 ] : Initializing transaction synchronization
    [TransactionAspectSupport,197 ] : Getting transaction for method 'storeProperty' in class [com.level3.sldb.framework.dao.DAOCommonIF]
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] bound to thread [main]
    [HibernateTransactionManager,345 ] : Found thread-bound session [net.sf.hibernate.impl.SessionImpl@48ff68] for Hibernate transaction
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.jdbc.datasource.ConnectionHold er@194adaa] for key [org.springframework.jdbc.datasource.SingleConnecti onDataSource@16b69d7] bound to thread [main]
    [AbstractPlatformTransactionManager,195 ] : Using transaction object [org.springframework.orm.hibernate.HibernateTransac tionObject@7148e9]
    [AbstractPlatformTransactionManager,248 ] : Participating in existing transaction
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] bound to thread [main]
    [ SessionImpl,1387 ] : saveOrUpdate() unsaved instance
    [ BatcherImpl,200 ] : about to open: 0 open PreparedStatements, 0 open ResultSets
    [ BatcherImpl,226 ] : select PROPERTIES_SEQ.nextval from dual
    [ BatcherImpl,249 ] : preparing statement
    [ SequenceGenerator,81 ] : Sequence identifier generated: 493
    [ BatcherImpl,207 ] : done closing: 0 open PreparedStatements, 0 open ResultSets
    [ BatcherImpl,269 ] : closing statement
    [ SessionImpl,778 ] : generated identifier: 493
    [ SessionImpl,825 ] : saving [com.level3.sldb.framework.dao.dto.PropertyDTO#493]
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] bound to thread [main]
    [TransactionAspectSupport,240 ] : Invoking commit for transaction on method 'storeProperty' in class [com.level3.sldb.framework.dao.DAOCommonIF]
    [TransactionAspectSupport,197 ] : Getting transaction for method 'loadProperty' in class [com.level3.sldb.framework.dao.DAOCommonIF]
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] bound to thread [main]
    [HibernateTransactionManager,345 ] : Found thread-bound session [net.sf.hibernate.impl.SessionImpl@48ff68] for Hibernate transaction
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.jdbc.datasource.ConnectionHold er@194adaa] for key [org.springframework.jdbc.datasource.SingleConnecti onDataSource@16b69d7] bound to thread [main]
    [AbstractPlatformTransactionManager,195 ] : Using transaction object [org.springframework.orm.hibernate.HibernateTransac tionObject@b28f30]
    [AbstractPlatformTransactionManager,248 ] : Participating in existing transaction
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] bound to thread [main]
    [ SessionImpl,1986 ] : loading [com.level3.sldb.framework.dao.dto.PropertyDTO#493]
    [ SessionImpl,2083 ] : attempting to resolve [com.level3.sldb.framework.dao.dto.PropertyDTO#493]
    [ SessionImpl,2099 ] : resolved object in session cache [com.level3.sldb.framework.dao.dto.PropertyDTO#493]
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] bound to thread [main]
    [TransactionAspectSupport,240 ] : Invoking commit for transaction on method 'loadProperty' in class [com.level3.sldb.framework.dao.DAOCommonIF]
    [TransactionAspectSupport,197 ] : Getting transaction for method 'deleteProperty' in class [com.level3.sldb.framework.dao.DAOCommonIF]
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] bound to thread [main]
    [HibernateTransactionManager,345 ] : Found thread-bound session [net.sf.hibernate.impl.SessionImpl@48ff68] for Hibernate transaction
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.jdbc.datasource.ConnectionHold er@194adaa] for key [org.springframework.jdbc.datasource.SingleConnecti onDataSource@16b69d7] bound to thread [main]
    [AbstractPlatformTransactionManager,195 ] : Using transaction object [org.springframework.orm.hibernate.HibernateTransac tionObject@ce88d2]
    [AbstractPlatformTransactionManager,248 ] : Participating in existing transaction
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] bound to thread [main]
    [ SessionImpl,1159 ] : deleting a persistent instance
    [ SessionImpl,1179 ] : deleting [com.level3.sldb.framework.dao.dto.PropertyDTO#493]
    [TransactionSynchronizationManager,117 ] : Retrieved value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] bound to thread [main]
    [TransactionAspectSupport,240 ] : Invoking commit for transaction on method 'deleteProperty' in class [com.level3.sldb.framework.dao.DAOCommonIF]
    [AbstractPlatformTransactionManager,495 ] : Triggering beforeCommit synchronization
    [AbstractPlatformTransactionManager,510 ] : Triggering beforeCompletion synchronization
    [AbstractPlatformTransactionManager,372 ] : Initiating transaction commit
    [HibernateTransactionManager,459 ] : Committing Hibernate transaction on session [net.sf.hibernate.impl.SessionImpl@48ff68]
    [ JDBCTransaction,59 ] : commit
    [ SessionImpl,2246 ] : flushing session
    [ SessionImpl,2439 ] : Flushing entities and processing referenced collections
    [ SessionImpl,2780 ] : Processing unreferenced collections
    [ SessionImpl,2794 ] : Scheduling collection removes/(re)creates/updates
    [ SessionImpl,2270 ] : Flushed: 1 insertions, 0 updates, 1 deletions to 1 objects
    [ SessionImpl,2275 ] : Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
    [ Printer,75 ] : listing entities:
    [ Printer,82 ] : com.level3.sldb.framework.dao.dto.PropertyDTO{valu e=MY_TEST_PROP, lastUpdatedUser=null, description=null, lastUpdated=null, name=MY_TEST_PROP, propertyId=493}
    [ SessionImpl,2359 ] : executing flush
    [ EntityPersister,453 ] : Inserting entity: [com.level3.sldb.framework.dao.dto.PropertyDTO#493]
    [ BatcherImpl,200 ] : about to open: 0 open PreparedStatements, 0 open ResultSets
    [ BatcherImpl,226 ] : insert into PROPERTIES (NAME, VALUE, DESCRIPTION, LAST_UPDATED, LAST_UPDATED_USER, PROPERTY_ID) values (?, ?, ?, ?, ?, ?)
    [ BatcherImpl,249 ] : preparing statement
    [ EntityPersister,388 ] : Dehydrating entity: [com.level3.sldb.framework.dao.dto.PropertyDTO#493]
    [ NullableType,46 ] : binding 'MY_TEST_PROP' to parameter: 1
    [ NullableType,46 ] : binding 'MY_TEST_PROP' to parameter: 2
    [ NullableType,41 ] : binding null to parameter: 3
    [ NullableType,41 ] : binding null to parameter: 4
    [ NullableType,41 ] : binding null to parameter: 5
    [ NullableType,46 ] : binding '493' to parameter: 6
    [ BatchingBatcher,28 ] : Adding to batch
    [ BatchingBatcher,50 ] : Executing batch size: 1
    [ BatchingBatcher,58 ] : success of batch update unknown: 0
    [ BatcherImpl,207 ] : done closing: 0 open PreparedStatements, 0 open ResultSets
    [ BatcherImpl,269 ] : closing statement
    [ EntityPersister,570 ] : Deleting entity: [com.level3.sldb.framework.dao.dto.PropertyDTO#493]
    [ BatcherImpl,200 ] : about to open: 0 open PreparedStatements, 0 open ResultSets
    [ BatcherImpl,226 ] : delete from PROPERTIES where PROPERTY_ID=?
    [ BatcherImpl,249 ] : preparing statement
    [ NullableType,46 ] : binding '493' to parameter: 1
    [ BatchingBatcher,28 ] : Adding to batch
    [ BatchingBatcher,50 ] : Executing batch size: 1
    [ BatchingBatcher,58 ] : success of batch update unknown: 0
    [ BatcherImpl,207 ] : done closing: 0 open PreparedStatements, 0 open ResultSets
    [ BatcherImpl,269 ] : closing statement
    [ SessionImpl,2824 ] : post flush
    [ SessionImpl,585 ] : transaction completion
    [ JDBCTransaction,103 ] : re-enabling autocommit
    [AbstractPlatformTransactionManager,540 ] : Triggering afterCompletion synchronization
    [TransactionSynchronizationManager,234 ] : Clearing transaction synchronization
    [TransactionSynchronizationManager,165 ] : Removed value [org.springframework.orm.hibernate.SessionHolder@13 41e11] for key [net.sf.hibernate.impl.SessionFactoryImpl@15b555] from thread [main]
    [TransactionSynchronizationManager,165 ] : Removed value [org.springframework.jdbc.datasource.ConnectionHold er@194adaa] for key [org.springframework.jdbc.datasource.SingleConnecti onDataSource@16b69d7] from thread [main]
    [HibernateTransactionManager,535 ] : Closing Hibernate session [net.sf.hibernate.impl.SessionImpl@48ff68] after transaction
    [ SessionFactoryUtils,572 ] : Closing Hibernate session
    [ SessionImpl,573 ] : closing session
    [ SessionImpl,3336 ] : disconnecting session
    [ SessionImpl,585 ] : transaction completion


    Thanks in advance.

    Franz[/code]

  • #2
    Franz,
    what you shows here is absolutely normal:
    Code:
    <bean id="com.level3.sldb.framework.dao.DAOCommonIF" parent="baseTransactionProxy"> 
      <property name="target"> 
        <bean class="com.level3.sldb.framework.dao.DAOCommon"> 
          <property name="sessionFactory">ref local="sessionFactory"/></property> 
        </bean> 
      </property> 
    </bean>
    
      try &#123; 
         ClassFactoryIF cf = new ClassFactory&#40;&#41;; 
         DAOCommonIF dao = &#40;DAOCommonIF&#41; cf.getObject&#40;DAOCommonIF.class&#41;; 
         PropertyDTO p = new PropertyDTO&#40;&#41;; 
         logger.log&#40;Priority.WARN, "STORING PROPERTY"&#41;; 
         dao.storeProperty&#40;p&#41;; 
         logger.log&#40;Priority.WARN, "STORED PROPERTY"&#41;; 
         logger.log&#40;Priority.WARN, "DELETING PROPERTY"&#41;; 
         dao.deleteProperty&#40;p&#41;; 
         logger.log&#40;Priority.WARN, "DELETED PROPERTY"&#41;;
    This excerpt means that Spring will spans each DAOCommon method call inside a new Transaction (Since you are using PROPAGATION_REQUIRED and no Transaction exists before the call).
    If you need to span multiple calls in the same transaction, create a Service class that calls the DAO method, then apply declarative transaction demarcation to the service method instead of DAO methods:
    Code:
      <bean id="service" class="some.service.ClassImpl">
        <property name="dao"><ref local="daoBean"/></property>
      </bean>
    
      public class ClassImpl &#123;
        public void methodOne&#40;&#41; &#123;
          dao.method1&#40;&#41;;
          dao.method2&#40;&#41;;
        &#125;
      &#125;
    HTH

    Comment


    • #3
      That sounds reasonable...although the code below is in an EJB which I would assume is transactional since I can reference an EJB Context object and roll back the transaction. It is my understanding that a CMT EJB will implicitly start a JTA transaction...and the Spring/Hibernate combo should automagically use it. Am I incorrect? I wouldn't think that I have to have a wrapper around each of my DAOs in order to reuse a transaction across them if I am using an EJB to begin/commit my transactions.

      Thanks in advance.

      Code:
      public Class SomeEJB extends StatelessSessionBean...
      
       try &#123; 
           ClassFactoryIF cf = new ClassFactory&#40;&#41;; 
           DAOCommonIF dao = &#40;DAOCommonIF&#41; cf.getObject&#40;DAOCommonIF.class&#41;; 
           PropertyDTO p = new PropertyDTO&#40;&#41;; 
           logger.log&#40;Priority.WARN, "STORING PROPERTY"&#41;; 
           dao.storeProperty&#40;p&#41;; 
           logger.log&#40;Priority.WARN, "STORED PROPERTY"&#41;; 
           logger.log&#40;Priority.WARN, "DELETING PROPERTY"&#41;; 
           dao.deleteProperty&#40;p&#41;; 
           logger.log&#40;Priority.WARN, "DELETED PROPERTY"&#41;;

      Comment


      • #4
        AFAIK, Spring is not aware of existing JTA transactions. When you call a method that is configured for Transactions, Spring JTATransactionManager looks up a transaction (from container), executes beginTransaction and calls your method. After the method resturns, the transaction manager calls commit or rollback, depending on the method return status. This is equivalent to:
        Code:
              TransactionStatus status = tm.getTransaction&#40;def&#41;; 
              PropertyDTO p = getTestProperty&#40;&#41;; 
              daoImpl.storeProperty&#40;p&#41;; 
              tm.commit&#40;status&#41;;
        If you need to use the same transaction for two, or more methods, then you have to have a wrapper around your methods.
        This way, applying local transactions or JTA transactions is absolutely transparent since your application works the same way without editing the code.
        HTH

        Comment

        Working...
        X