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.
| Online: | 9 Members of 4089 |
| Forum: Seam Users |
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>
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.
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 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.
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.