Announcement Announcement Module
Collapse
No announcement yet.
Transaction not propagated (in OSGi environment) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Transaction not propagated (in OSGi environment)

    Hi,

    Yesterday I posted this thread for reporting problem I had with transaction propagation in an OSGi environment using spring-dm. I don't really know if this problem is due to Spring-dm so I made a few more tests and here is a more detailed scenario.
    I have a business bean, called CIMService which has the following method inside:

    Code:
    	@Transactional(readOnly=true)
    	private CIMProperty findParentClassProperty(CIMClass baseClass, String propertyName) {
    		logger.debug("-> CIMService.findParentClassProperty ");
    //		CIMClass superClass = baseClass.getParentClass();
    		CIMClass superClass = cimClassDao.read(baseClass.getParentClass().getId() );
    		logger.debug("---");
    
    		while(superClass != null) {
    			for(CIMProperty prop : superClass.getProperties()) {
    				if(propertyName.equalsIgnoreCase(prop.getName())) {
    					logger.debug("<- CIMService.findParentClassProperty");
    					return prop;
    				}
    			}
    			superClass = superClass.getParentClass();
    		}
    		logger.debug("<- CIMService.findParentClassProperty");
    		return null;
    	}
    CIMClass is mapped by hibernate with the following configuration:
    Code:
    	<joined-subclass name="org.escapek.domain.cim.CIMClass" 
    			extends="org.escapek.domain.cim.CIMObject" table="CIM_CLASS">
    		<key column="CLASS_ID"/>
    		<many-to-one name="parentClass" column="PARENT_CLASS_FK" lazy="false" />
    		<many-to-one name="schema" column="SCHEMA_FK" lazy="false"/>
    		<many-to-one name="model" column="CIM_MODEL_FK" lazy="false" />
    		<set name="properties" inverse="true" lazy="true">
    			<key column="CLASS_FK"/>
    			<one-to-many class="org.escapek.domain.cim.CIMProperty"/>
    	    </set>
    		<set name="methods" inverse="true" lazy="false">
    			<key column="CLASS_FK"/>
    			<one-to-many class="org.escapek.domain.cim.CIMMethod"/>
    	    </set>
    		<property name="associationClass" column="ASSOCIATION_CLASS"/>
    		<property name="keyedClass" column="KEYED_CLASS"/>
    		<property name="abstractClass" column="ABSTRACT_CLASS"/>
    	</joined-subclass>
    As you can see the properties set is declared as lazy. This is where my problems are coming from. Indeed when CIMService.findParentClassProperty tries to iterate superClass.getProperties() I get LazyInitializationException.
    The first thing I checked is that the method was running in a transaction (same hibernate session) than the session which retrieved baseClass. To make sure i've changed the method to call the cimClassDao to get the superClass in the current transaction (see first line commented).
    This doesn't change the problem ...

    The code for CIMClassDao.read() is :
    Code:
    	@Transactional(readOnly=true)
        public CIMClass read(String idType) {
    		logger.debug("-> CIMClassDao.read");
    		CIMClass cClass = (CIMClass)getHibernateTemplate().get(CIMClass.class, idType);
    		logger.debug("<- CIMClassDao.read");	
    		return cClass;
        }
    To be complete here is the debug trace of the CIMService.findParentClassProperty method execution:
    Code:
    2008-08-05 12:04:01,884 [Thread-0] DEBUG org.escapek.server.cim.impl.internal.CIMService:603 - -> CIMService.findParentClassProperty 
    2008-08-05 12:04:01,885 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@11dc87]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitStartingEvent[source=org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean@3f6c10]
    2008-08-05 12:04:01,885 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@11dc87]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitEndedEvent[source=org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean@3f6c10]
    2008-08-05 12:04:01,886 [Thread-0] DEBUG o.s.t.a.AnnotationTransactionAttributeSource:107 - Adding transactional method [read] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly]
    2008-08-05 12:04:01,886 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:346 - Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@82b1a9]
    2008-08-05 12:04:01,886 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:374 - Creating new transaction with name [org.escapek.domain.orm.dao.IGenericDao.read]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
    2008-08-05 12:04:01,887 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:496 - Opened new Session [org.hibernate.impl.SessionImpl@5e0a84] for Hibernate transaction
    2008-08-05 12:04:01,887 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:507 - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@5e0a84]
    2008-08-05 12:04:01,887 [Thread-0] DEBUG o.springframework.jdbc.datasource.DataSourceUtils:155 - Setting JDBC Connection [jdbc:derby:EscapeKEmbeddedDB, UserName=nico, Apache Derby Embedded JDBC Driver] read-only
    2008-08-05 12:04:01,888 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:572 - Exposing Hibernate transaction as JDBC transaction [jdbc:derby:EscapeKEmbeddedDB, UserName=nico, Apache Derby Embedded JDBC Driver]
    2008-08-05 12:04:01,888 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:186 - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@48ceb] for key [org.apache.commons.dbcp.BasicDataSource@6a34c1] to thread [Thread-0]
    2008-08-05 12:04:01,888 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:186 - Bound value [org.springframework.orm.hibernate3.SessionHolder@bfc909] for key [org.hibernate.impl.SessionFactoryImpl@284aa8] to thread [Thread-0]
    2008-08-05 12:04:01,889 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:261 - Initializing transaction synchronization
    2008-08-05 12:04:01,889 [Thread-0] DEBUG o.e.domain.orm.hibernate.internal.dao.CIMClassDao:50 - -> CIMClassDao.read
    2008-08-05 12:04:01,889 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@bfc909] for key [org.hibernate.impl.SessionFactoryImpl@284aa8] bound to thread [Thread-0]
    2008-08-05 12:04:01,890 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@bfc909] for key [org.hibernate.impl.SessionFactoryImpl@284aa8] bound to thread [Thread-0]
    2008-08-05 12:04:01,890 [Thread-0] DEBUG o.springframework.orm.hibernate3.HibernateTemplate:410 - Found thread-bound Session for HibernateTemplate
    2008-08-05 12:04:01,902 [Thread-0] DEBUG o.springframework.orm.hibernate3.HibernateTemplate:435 - Not closing pre-bound Hibernate Session after HibernateTemplate
    2008-08-05 12:04:01,902 [Thread-0] DEBUG o.e.domain.orm.hibernate.internal.dao.CIMClassDao:54 - <- CIMClassDao.read
    2008-08-05 12:04:01,903 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:880 - Triggering beforeCommit synchronization
    2008-08-05 12:04:01,903 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:893 - Triggering beforeCompletion synchronization
    2008-08-05 12:04:01,903 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:707 - Initiating transaction commit
    2008-08-05 12:04:01,904 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:651 - Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl@5e0a84]
    2008-08-05 12:04:01,904 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:906 - Triggering afterCommit synchronization
    2008-08-05 12:04:01,904 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:922 - Triggering afterCompletion synchronization
    2008-08-05 12:04:01,904 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:315 - Clearing transaction synchronization
    2008-08-05 12:04:01,905 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:232 - Removed value [org.springframework.orm.hibernate3.SessionHolder@bfc909] for key [org.hibernate.impl.SessionFactoryImpl@284aa8] from thread [Thread-0]
    2008-08-05 12:04:01,905 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:232 - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@48ceb] for key [org.apache.commons.dbcp.BasicDataSource@6a34c1] from thread [Thread-0]
    2008-08-05 12:04:01,905 [Thread-0] DEBUG o.springframework.jdbc.datasource.DataSourceUtils:202 - Resetting read-only flag of JDBC Connection [jdbc:derby:EscapeKEmbeddedDB, UserName=nico, Apache Derby Embedded JDBC Driver]
    2008-08-05 12:04:01,906 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:730 - Closing Hibernate Session [org.hibernate.impl.SessionImpl@5e0a84] after transaction
    2008-08-05 12:04:01,906 [Thread-0] DEBUG o.s.orm.hibernate3.SessionFactoryUtils:774 - Closing Hibernate Session
    2008-08-05 12:25:42,136 [Thread-0] DEBUG org.escapek.server.cim.impl.internal.CIMService:606 - ---
    2008-08-05 12:04:01,908 [Thread-0] ERROR org.hibernate.LazyInitializationException:19 - failed to lazily initialize a collection of role: org.escapek.domain.cim.CIMClass.properties, no session or session was closed
    Now where OSGi comes ... In fact cimClassDao implementation resides in another osgi bundle and is exposed a an OSGi service thanks to spring-dm. At runtime the service is injected into CIMService bean.

    Trace shows that the transaction and the hibernate session are closed when the cimClassDao.read() methods ends. I don't understand why since the transaction should be propagated due to @Transactional. Could this be due to the fact that the dao is accessed through some osgi proxy ?

    Also, note that when setting the properties set to lazy="false" everything goes fine.

  • #2
    Tell me if i'm wrong ...

    my

    Code:
    <tx:annotation-driven transaction-manager="txManager"/>
    ,which cares about @Transactional, is declared in the same bundle as the dao. Therefore i think AOP only works inside that bundle and transaction are only managed for calls inside the bundle. As my CIMService is outside the bundle methods calls are not intercepted by the transaction manager. Then cimService method are called outside any transaction, ie in independant hibernate sessions, which causes the LazyInitExeption.

    So i need to have a transaction manager which would works for all bundles. May be having the transaction manager registered as an osgi service could help....

    Comment


    • #3
      Ok, i think i've found a fix (for now). Discussion will continue on the original thread as it is more related to OSGi than pure data access.

      Sorry for duplicates posts

      Comment

      Working...
      X