Hi,
I'm going to embeed a workflow engine (Jbpm2) into my application. The target platform for running my application is Spring framework. JBpm2's is using Hibernate as its persistence layer.
Before I go all the way embeeding Jbpm2 into my application, I conduct several small experiments. I'm concerned about transaction management. Here's one of the scenario that I tried:
My application has a service object, named Kwik. When Kwik::sayHi() is invoked, it:
[1] Perform db updates (on its own)
[2] Tell a process instance to proceed to next state (by calling Jbpm's ExecutionService::endState(..))
[3] Invoke another service object in my application (Kwak).
All those operation should be performed in a single transaction. That means: if step #3 fails, the process instance (whose state has been updated on step #2) should be automatically rolled back to its previous state.
In this experiment, I haven't use JBpm2. I used my own code, KwekImpl2, that behaves like Jbpm2 (in term of persistence operation). I mean, just like Jbpm2, KwekImpl2 builds the hibernate Configuration, and SessionFactory on its own. It also obtains Hibernate Session directly by calling SessionFactory. Normally, application that is intended to run on Spring, should open hibernate Session by calling Spring's SessionFactoryUtilL::openSession(...), in order to play nicely with Spring's transaction management. KwekImpl2 also starts a hibernate transaction on its own, by calling session.beginTransaction(), and performs commit on that transaction at the end of sayHo().
Important sources related to my experiment are: Main11.java, KwekImpl2, appctx13.xml, and hibernate.properties (
http://www.geocities.com/don_raka/latih ... ernate.zip ). The scenario described above failed. I've tried all configurations I can think of (related to distributed transaction management) both on Spring side (appctx13.xml) and Hibernate side (hibernate.properties). I'm using Jotm 1.5.3 as distributed transaction manager. Jotm's Current is bound to JNDI as "java:comp/UserTransaction" (such that Hibernate's JTATransaction can lookup that object from JNDI, @see JTATransaction::beginTransaction). I've configured both the spring & hibernate to use JTA transaction.
After several rounds of debugging, I found out that by the time JTATransaction::commit() is invoked -- see KwekImpl2.java, line 41 -- session.flush() is called. And apparently that transaction rollback that results from failure on step #3 didn't affect that modification.
I don't understand, it seems like hibernate's transaction is not aware that it takes part in a transaction that was started by other part of the application (Spring).
Please let me know what I've missed / done wrong. Perhaps any missing / wrong configuration?
Best regards & TIA,
Cokorda Raka (
http://www.jroller.com/page/donraka )
--------
Hibernate version: 2.1.6
Mapping documents:
Code between sessionFactory.openSession() and session.close():
Full stack trace of any exception that occurs:
Name and version of the database you are using: hsqldb 1.7.2
Debug level Hibernate log excerpt: