ah yes. i'll check tomorrow on how fast we can fix this.
the only way that i could configure hibernate with jta was if i address it from inside an ejb and use cmt (bmt should also be possible).
the idea was that the web app console would talk to jbpm by means of the command pattern. then the console has to be configured with a command service implementation that takes commands and executes them. So the command service is pluggable. The POJO implementation would just create a jbpm context and execute the command. The enterprise version of the command service delegates to the command service SLSB. That SLSB demarcates the transaction.
this is all implemented except for the webconsole using the command pattern. I don't know where we stand on that. David, can you comment. I know this has not been in the priorities for you in the 3.2 release. So no problem if it's not done. Just curious on how difficult you think this would be. I might do this myself.
Alternatively, we could consider introducing configurable BMT in the webconsole (with a filter?)
I'll have a closer look tomorrow morning.
What benefit does using an ejb for this purpose provide, apart from transaction management?
I think making transaction handling configurable is more appropriate. The web application should be able to use the jbpm api without adding a layer of abstraction upon it. The only difference in an enterprise environment should be how jbpm manages the transaction internally. In the standalone case it would use hibernate directly (for example); in the enterprise case it would use JTA to locate/create and manage the transaction. But it should all happen behind the scenes; the jbpm txn management api should handle this transparently.
I'm not sure I like the idea of redoing the web application actions in terms of the command pattern, because I wouldn't expect users to have to think in those terms; in many ways this application is a definitive jbpm example application.
Amendment: I should say, I wouldn't want to put this kind of implementation inside of the web application.
If you think the jbpm core api should have a (replacement or supplemental) command pattern-based interface, that would work.
Looking around *yet more*, it looks like there is at least a partial command api in there... I dunno, I guess I'll do whatever you'd like :-)
So what you need to do to make it configurable is in two files:
1) hibernate.cfg.xml needs to be transaction enabled - see the one in jbpm-configs (or perhaps remove your copy from classes when deployed as part of the ear ? will you find it on the application classpath - I think so?)
By the way, I think this file should use JTA not CMT. CMT assume the container has always started a transaction, and hibernate will never attempt to. If JTA, then hibernate will start one if none exists. If you are not using the CommandInterface, you need Hibernate to start one.
2) jbpm.cfg.xml - need to specify isTransactionEnabled to false. Again see the one in jbpm-configs.
I will remove the versions of these files from the web-console.war, change CMT to JTA, and see if the correct ones are picked up.
Also, I don't think the console should use the Command interface at this point in the 3.2 lifecycle. I don't think the Command interface has been tested thoroughly, and though it's meant to be extensible, you might wind up have to create several new commands to do what you need (which could be time consuming).
Actually, I see that the jbpm-console.war that is inside the jbpm-enterprise ear is different and DOES NOT contain the hibernate and jbpm.cfg.xml files.
So I think the problem is the CMT vs JTA, and will make this change and re-test.
Hum, changing the TransactionFactory from CMT to JTA did not solve the problem, but setting
isCurrentSessionEnabled to false in jbpm.cfg.xml did !!!!!
Tom, you probably want to check with the Hibernate guys on this; my understanding is that if you invoked getCurrentSession and there was none, hibernate would create a session for you. Somehow if it is creating it, it is not creating a transaction along with it.
in the enterprise.ear, the configurations are packaged in a separate jar file called jbpm-configs.jar
these are the relevant properties in the hibernate.cfg.xml
<property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property> <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property> <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property> <property name="hibernate.connection.datasource">java:/JbpmDS</property> <property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property> <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
and this is the jbpm.cfg.xml part of the persistence/tx configs
<service name="persistence"> <factory> <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory"> <field name="isCurrentSessionEnabled"> <true /> </field> <field name="isTransactionEnabled"> <false /> </field> </bean> </factory> </service>
if you change to JTA, you might need to set the isTransactionEnabled property to true. i don't know these configs at all. i'll check the docs and get back if i find anything there.
From the hibernate docs:
3.8.3. Current Session context management with JTA
The easiest way to handle Sessions and transactions is Hibernates automatic "current" Session management. See the discussion of Section 2.5, ?Contextual Sessions?. Using the "jta" session context, if there is no Hibernate Session associated with the current JTA transaction, one will be started and associated with that JTA transaction the first time you call sessionFactory.getCurrentSession(). The Sessions retrieved via getCurrentSession() in "jta" context will be set to automatically flush before the transaction completes, close after the transaction completes, and aggressively release JDBC connections after each statement. This allows the Sessions to be managed by the lifecycle of the JTA transaction to which it is associated, keeping user code clean of such management concerns. Your code can either use JTA programmatically through UserTransaction, or (recommended for portable code) use the Hibernate Transaction API to set transaction boundaries. If you run in an EJB container, declarative transaction demarcation with CMT is preferred.
So you might want to give it a try with isTransactionEnabled set to true. I hope that hibernate is so clever to ignore the Transaction.commits in the jbpmContext.close()... should be.
Yes, I made the changes I described in jbpm-configs.jar. isTransactionEnabled should not be set to true; if it is not only would jBPM try to demarcate the transactions, but my understaning is jBPM would also close the hibernate session, wchich should foul everything up.
You see from the the description of CMT why it is not a fit for jBPM. The web console (as currently implemented / deployed), does NOT run in / use the EJB container. Not can we guarantee that other user applications would just because they deployed jbpm-enterprise.ear (although you would expect them to). JTA is flexible because it allows for both EJB and non-EJB applications.
If the jbpm-console were to be modified to only use the Command SLSB interface, then CMT might be a better fit for jBPM enterprise.
As far as the documentation on getCurrentSession, in the past (in another project) it appeared to work that way. However in testing with jBPM the process deployment did not work until I set isCurrentSessionEnabled to false. You might want to test this out and see if you get the same result.
Well the transaction issues have gone away with the changes I described, however I updated with the latest from CVS to test out some other changes and now when I deploy from the GPD I get the message:
FileUploadExcepption: the request was rejected because no multi-part boundary was found
This is the same processdefinition that uploaded successfully yesterday.
The console appears to have the latest commons-fileupload.jar. However I am using the 3.0.12 GPD that is installed in JBoss-IDE.