Monday, August 16, 2010

Custom Hibernate configuration for the JBPM console

That Hibernate configuration exception still bothered me, so I looked into it as well.

It basically says that the JBPM console can find the application's Hibernate configuration file but fails to create the Hibernate Configuration object out of the file. The reason: the application is using Hibernate Annotations with corresponding entries in the config file, but the JBPM console tries to read the file as a plain Hibernate configuration (with xml mapping files). No surprise this fails.

I looked at the application code to see how the configuration file is read and how the Configuration object is used. The application has some utility class to load the configuration as Hibernate Annotation configuration. Each time after the application asks JBPM for a new JbpmContext it does jbpmContext.setSessionFactory(Util.getHibernateSessionFactory()). The JBPM console uses the Configuration the same way (jbpmContext.setSessionFactory), it just loads it differently.

No, I do not want to change the code of the JBPM console. I need to find a different way to make sure the JBPM console can find the correct SessionFactory object. No, actually I do not care about the console: it just passes the SessionFactory to JBPM. I need to make sure JBPM sees the correct SessionFactory object. What choices do I have? Option 1: register the Hibernate SessionFactory in JNDI, built-in Hibernate functionality. Option 2: there is a possibility to replace the way the JBPM configuration file is loaded so it is possible to create a custom JbpmContext, or, in my case, just a standard JbpmContext, but with the correct Hibernate SessionFactory.

Some experiments proved that it is not that easy. Registering a SessionFactory in JNDI does not work out of the box because both OpenEJB and OC4J treat the JNDI name as a local name, and the SessionFactory registered in one place is not visible in the console. And the reading of the JBPM configuration is "all or nothing" solution: there is just no way to get the created JbpmContext right after it is created without duplicating a lot of the existing JBPM code.

I think I would eventually make either of the solution work but I got distracted. Not for the first time a much better solution just came to me while I was busy with some other things.

JbpmContext itself does not do anything with SessionFactory: the only thing JbpmContext.setSessionFactory() does is passing the SessionFactory down to PersistencyService. And PersistencyService is configured in jbpm.cfg.xml (org.jbpm.persistence.db.DbPersistenceServiceFactory in our case). The solution: create the subclass of DbPersistenceServiceFactory that does just one thing: passes the application's SessionFactory to the superclass, the rest is up to the superclass. With the subclass registered in jbpm.cfg.xml the console does not give the Hibernate configuration errors any more; instead it nicely displays our processes.

The solution also makes all those jbpmContext.setSessionFactory(Util.getHibernateSessionFactory()) in the application code redundant, so I deleted them: less code less potential problems.

No comments:

Post a Comment