Help

Controls

PermLinkWikiLink

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Forum: Seam Users Forum ListTopic List
11. Jul 2008, 18:51 CET | Link

I'm having problem when an exception is raised in one of the action handlers of my jpdl process. The changes made through the seam managed hibernate session gets rolled back, but changes made in jbpm session gets flushed/commited.

I'm using the same sessionfactory for both jbpm and my app. While doing the debug, even with rollbacks being set after the exception was thrown, jbpmContext.close() gets called during destroy of ManagedJmbpmContext, which cause jbpm's session to flush.

Would anyone be able to guide me on how to fix this issue?

hibernate.properties

hibernate.show_sql=true
hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
hibernate.hbm2ddl.auto=update

hibernate.connection.datasource=java:/prototypeDS
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

hibernate.transaction.factory_class=org.hibernate.transaction.JDBCTransactionFactory
hibernate.transaction.flush_before_completion=true

jbpm.cfg.xml, com.rfc.util.seam.jbpm.SeamSessionFactory is a class that gets the SessionFactory from seam.


<jbpm-configuration>  

  <bean name="seamSessionFactoryCreator" 
         class="com.rfc.util.seam.jbpm.SeamSessionFactory" 
         singleton="true"/>	           
  
  <bean name="seamSessionFactory" 
    	class="org.hibernate.SessionFactory" 
    	singleton="true">
        <constructor factory="seamSessionFactoryCreator" method="getSessionFactory" >
	      <parameter class="java.lang.String">
	        <string>hibernateSessionFactory</string>
	      </parameter>		      
   		</constructor>         
  </bean>      
   
  <jbpm-context>
    <service name="persistence">
       <factory>
          <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
             <field name="isTransactionEnabled"><false/></field>
              <property name="sessionFactory">
              	  <ref bean="seamSessionFactory" />       	
              </property>             
          </bean>
       </factory>
    </service>
    <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
    <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
    <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
    <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
    <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
  </jbpm-context>
</jbpm-configuration>

2 Replies:
12. Jul 2008, 06:42 CET | Link

Is this a bug? There's a similar issue on this post http://www.seamframework.org/Community/SeamJBPMTransactions.

I searched in Seam's JIRA, there's no issue filed for it yet.

14. Jul 2008, 20:18 CET | Link

I did some more digging into this. I'm using Seam with pojo and plain hibernate, no EJBs.

The main issue I found was even after rollback is called, ManagedJbpmContext.afterCompletion does not really do anything because the EventContext is still active. Later on during ManagedJbpmContext.destroy, the jbpmContext is closed and those changes that are stored in autoSave are still flushed.

To get around this problem, I overrode ManagedJbpmContext with an implementation that tries to clear and replace the managed jbpmContext during rollback. The method is shown below. SeamAwareDbPersistenceService is just a subclass of DbPersistenceService that exposes mustSessionBeFlushed to public, this is set to false during a rollback. Error still happens during the call to jbpmContext.close when jbpmContext tries to call autoSave, I have not found a way to clear this from jbpmContext.

public void afterCompletion(int status) {
	synchronizationRegistered = false;
	if (status == Status.STATUS_ROLLEDBACK) {
	// dont flush the session, clear it.
	SeamAwareDbPersistenceService dbps = (SeamAwareDbPersistenceService) jbpmContext
		.getServices().getPersistenceService();
		if (dbps.getSession() != null) {
			dbps.getSession().clear();
		}			
		dbps.setMustSessionBeFlushed(false);
		try {
			jbpmContext.close();
		} catch (Throwable t) {
			//error still happens because of 
			//jbpmContext trying to run autoSave.
			//this should be cleared.
			log.warn("Error closing jbpmContext.", t);
		} finally {
			jbpmContext = Jbpm.instance().getJbpmConfiguration()
				.createJbpmContext();
		}
	}

	if (!Contexts.isEventContextActive()) {
		// in calls to MDBs and remote calls to SBs, the
		// transaction doesn't commit until after contexts
		// are destroyed, so wait until the transaction
		// completes before closing the session
		// on the other hand, if we still have an active
		// event context, leave it open
		closeContext();
	}
}

Aside from this, I used JTATransaction strategy on my hibernate.properties.

hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.transaction.flush_before_completion=true

Please let me know if this can cause some unforseen problems. Should ManagedJbpmContext be clearing the jbpmContext during rollback?

I appreciate your insight into this.