[jboss-user] [jBPM Development] - Injected hibernate SessionFactory is not used by jBPM 4.3?

Guido Helmers do-not-reply at jboss.com
Sun Apr 11 13:04:41 EDT 2010

Guido Helmers [http://community.jboss.org/people/helmers] created the discussion

"Injected hibernate SessionFactory is not used by jBPM 4.3?"

To view the discussion, visit: http://community.jboss.org/message/536777#536777

Hi there,

I'm using jBPM 4.3 and I want jBPM to use my own SessionFactoryImpl object, instead of creating its own. I'm doing the following to inject my SessionFactory into jBPM:

new Configuration().setResource("jbpm/jbpm.cfg.xml").setHibernateSessionFactory(hibernateSessionFactory).buildProcessEngine();
But jBPM ignores what I pass in, and creates its own SessionFactory.
 Does anyone know what I should do to make this work? Is there an additional jBPM configuration property that I need to set? Could it be a bug in jBPM?
 I've attached a Maven project that you can use to debug this problem. I'll explain how you can debug it to see what's going wrong. If you want to know about the project structure (not really required to debug the jbpm problem), read the section at the end of this mail.
 +Note: We're using Guice for dependency injection; dependencies are configured in the *Module classes. Warp-persist is used for transaction management in Guice. I'm not sure if guice and warp-persist are in the central maven repos, so I've put those libraries in the lib folder.+
 How to debug
Import the maven project in your IDE.
(In Eclipse: mvn clean eclipse:clean eclipse:eclipse -Declipse.useProjectReferences=true -DdownloadSources=true -DdownloadJavadocs=true
 You may have to install the guice libraries in your local maven repository. Do a "mvn clean compile" to check whether the project is complete).
 Put a break point on the following lines / methods (basically everything in the code base related to a hibernate SessionFactory):
1.   My code:1.  JbpmLayerModule.provideProcessEngine()

2.   jBPM code:1.   ConfigurationImpl.setHibernateSessionFactory(Object)
2.   HibernateSessionDescriptor.construct(WireContext)
3.   HibernateSessionFactoryDescriptor.construct(wireContext)

 Now run IssueServiceIntegrationTest.testCreate() in debug mode. On the above breakpoints, you'll see information similar to the following:
 *[1.1]* hibernateSessionFactory=org.hibernate.impl.SessionFactoryImpl at 5c6c0a(id=92)
 *[2.1]* processEngineWireContext=WireContext "process-engine"(id=112)
 *[2.2]* [Indirectly called by CheckDbCmd.execute()] wireContext="transaction"(id=166)
It's doing this: sessionFactory = environment.get(SessionFactory.class);
When I look in the 'environment' variable, I see there are 2 contexts in there: A 'transaction' context and a 'process-engine' context. The 'transaction' context contains ZERO SessionFactory definitions. The 'process-engine' context contains TWO SessionFactory definitions:
* org.hibernate.impl.SessionFactory->ProvidedObjectDescriptor (with .providedObject=the one I passed in)
* org.hibernate.SessionFactory->HibernateSessionFactoryDescriptor (with .name="org.hibernate.SessionFactory", all other fields null).

So my SessionFactory is available in the 'process-engine' context, under key "org.hibernate.impl.SessionFactory"...
==> Problem: My SessionFactory is stored under key '...SessionFactoryImpl', not under '...SessionFactory'!
That's why we end up in the following HibernateSessionFactoryDescriptor:
 *[2.3]* It's doing this:
configuration = wireContext.get(Configuration.class);
SessionFactory sessionFactory = configuration.buildSessionFactory();
In other words, loading a new hibernate Configuration from scratch, and a new SessionFactory.
h3. Questions
It seems that in [3] (that is HibernateSessionDescriptor.construct()) something's going wrong.
* How can I have jBPM use the SessionFactory instance that was stored in the 'process-engine' WireContext, instead of using its own default mechanism to load hibernate configuration and construct a session factory?

*  Did I forget some configuration properties in the jbpm.cfg.xml?* Is it a bug in jBPM?
*  Isn't it scary that the 'process-engine' wireContext contain a mapping for 'SessionContext' and one for 'SessionContextImpl'. Depending on whether you're requesting the interface or implementation, you're obtaining a different session factory (I guess that's what this whole post is about...?)

 I do see that in HibernateSessionDescriptor, there's a 'factoryName' property. If this property is set, it will lookup the SessionFactory in the 'transaction' wireContext under that 'factoryName'. Two questions:
1. Can I set the 'factoryName' somehow, from a jbpm configuration file? How?
2. If so, will it make any difference? Because it will then be looking up the SessionFactory in the 'transaction' wireContext, instead of the 'process-engine' wireContext (in which my SesionFactory is contained).

h3. Background info on attached project
The project is called 'jbpmtest'. It's a multimodule maven project, with the following (slightly simplified) dependency graph: [ service -> dao -> test -> domain -> commons ].

 (About the domain: There's only one class in the domain, called 'Issue'. We store every Issue locally, and in addition an Issue has its own jBPM process instance; This is all managed by the IssueService. But this isn't relevant to the jBPM problem really..)
 The Guice module structure (comparable to Spring's application
 context) is as follows:
  |__ TestDataSourceModule
  |    |
  |    |__ JndiDataSourceCreator <-- Makes a datasource available under Jndi name 'jbpmtestDs'
  |__ DataLayerModule
  |    |
  |    |__ bind(Configuration).to(HibernateConfigurationProvider) (*)
  |    |
  |    |__ PersistenceModule
  |         |
  |         |__ HibernatePersistenceModule (**)
  |__ ServiceLayerModule
      |__ JbpmLayerModule (***)
 (*) Reads hibernate.cfg.xml and combines it with some other (programmatic) properties into a hibernate Configuration.
 (**) Created with "PersistenceService.usingHibernate().across(UnitOfWork.TRANSACTION).buildModule()",
 using (*).
 (***) The wiring of jBPM beans is done in the JbpmLayerModule. It constructs a ProcessEngine singleton, which in turn is used to provide
 the actual jBPM services (like RepositoryService, ExecutionService, etc.).
 jBPM's ProcessEngine is created like this:
    ProcessEngine provideProcessEngine(SessionFactory hibernateSessionFactory) {
        return new Configuration().setResource("jbpm/jbpm.cfg.xml")

 You can see that org.jbpm.api.Configuration is passed in a hibernateSessionFactory; it's the SessionFactory created by Guice (somewhere inside the PersistenceService).
 Please note that the whole Guice configuration isn't really relevant here, I just explained it for you to get a better understanding of the test project. The only interesting thing here is that JbpmLayerModule.provideProcessEngine() injects a SessionFactory object (provided by Guice!) into the jBPM Configuration, and that a later stage, jBPM seems to have constructed its own SessionFactory! I was hoping the SessionFactory to be a singleton, and that passing it into the jBPM Configuration causes jBPM to *not* read the hibernate.cfg.xml again and construct a second SessionFactory...


Reply to this message by going to Community

Start a new discussion in jBPM Development at Community

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-user/attachments/20100411/2176119a/attachment.html 

More information about the jboss-user mailing list