[jBPM Development] - How to provide my own transaction to jBPM?
by Guido Helmers
Guido Helmers [http://community.jboss.org/people/helmers] created the discussion
"How to provide my own transaction to jBPM?"
To view the discussion, visit: http://community.jboss.org/message/536887#536887
--------------------------------------------------------------
Hi,
we're using jBPM 4.3, the jBPM tables are part of a bigger database schema, also containing our own tables.
Our transactional service method looks like this:
@Transactional
public String create(Issue issue) {
// (1) (own stuff)
issueDao.persist(issue);
Map list = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
// ... etc
}
First we write some stuff to our own tables, then we tell jBPM to start a process. This is all done within one transactional method (I was hoping...).
*jbpm.cfg.xml:*
*tx.hibernate.cfg.xml:*
*The problem...*
The problem is that jBPM creates its own transaction, and does not take part in the transaction started by our own application (as you can see by writing an integration test that succeeds on steps [1] and [2], but uses a mockTaskService to throw an exception at [3] - what you see then is that our own tables are emptied (top-level transaction is rolled-back), but JBPM4_HIST_PROCINST is still filled, in other words [2] is executed in its own transaction and is not rolled back).
I tried to remove the "standard-transaction-interceptor" from tx.hibernate.cfg.xml hoping that jBPM would magically participate in my own transaction, but that doesn't make jBPM very happy.
Does anyone have an idea how I can tell jBPM to use my transaction, instead of starting its own?
I read in the jBPM 4 developer's guide:
http://docs.jboss.org/jbpm/v4/devguide/html_single/#d0e2216 http://docs.jboss.org/jbpm/v4/devguide/html_single/#d0e2216
that +"User provided transasctional resources such as JDBC connections or hibernate connections"+ is not yet available in jBPM4. I guess this feature is what I need... is it already implemented or in the pipeline? Does anyone know when this feature will be available, or if there is a workaround for it?
This post is related to my earlier post on the fact that jbpm4 does not use the hibernate SessionFactory injected into it:
https://community.jboss.org/thread/150549?tstart=0 https://community.jboss.org/thread/150549?tstart=0
In the test project attached to that issue, you can also see how transaction management in our application works... Perhaps the problem is solved as soon as the SessionFactory injection issue is solved?
Cheers,
Guido
--------------------------------------------------------------
Reply to this message by going to Community
[http://community.jboss.org/message/536887#536887]
Start a new discussion in jBPM Development at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&cont...]
15 years, 12 months
Re: [jboss-dev-forums] [JBoss Web Services Development] - CXF jms integration
by Jim Ma
Jim Ma [http://community.jboss.org/people/jim.ma] replied to the discussion
"CXF jms integration"
To view the discussion, visit: http://community.jboss.org/message/536798#536798
--------------------------------------------------------------
> Right, we need proper integration through SPI here. The point is that we need to trigger destination (queue) creation during deployment. That is done using the API a given AS container provides; for instance on AS trunk, right now we'd probably end up creating a configuration for HornetQ to be used by HornetQ deployers (HornetQCoreConfigRealDeployer ?).
> As Richard's correctly saying, we should not use those AS API directly in JBWS CXF in order to maintain proper abstraction, so we need to enrich the JBossWS SPI (few additions in org.jboss.wsf.spi.deployment might be enough) for having those info (it's probably just the name of the destinations) available in a container independent way. That part of the SPI could be populated by CXF specific deployment aspect that parses the provided or generated jboss-cxf.xml.
> Later in the chain, we'd have another deployment aspect (coming from the container integration) that uses the new SPI info to create the JMS medatadata (HornetQ conf, for isntance) and provides the requirements for the JMS deployers to run.
IMHO, we do not need to provide the function to trigger the desination creation. We always assume that user already have this Queue/Topic deployed before webservice jms endpoint deployment or the jms deployment is deployed with jms endpoint, like how the MDB is deployed.
> All this assumes we review the current WSDeploymentAspectDeployer that forces every deployment aspect to be bound to the web deployers, given the JBossWebMetaData input/ouput. I imagine some minor changes might also be required a bit earlier in the deployer chain.
Agreed. The WSDeploymentAspectDeployer is one of the key class we need to think about how to change its behavior and handle other deployment without JBossWebMetaData input/output.
At the moment , I think parsing the jms endpoint deployment descirptor (like jbossws-endpoint.xml) and creating the service and endpoint work should be put in front of WSDeploymentAspectDeployer chain. I am analysing it more to see what else we need to change .
> Jim, I'd encourage you to create branches like a did when working on cxf/jaxrpc issue and start doing changes there. Either Richard or me can help you step by step there, till we have something working that can be merged to trunk. This way you can also start now that 3.3.0 is not released yet (this work is targeted for 4.x)
Will do.
Thanks.
--------------------------------------------------------------
Reply to this message by going to Community
[http://community.jboss.org/message/536798#536798]
Start a new discussion in JBoss Web Services Development at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&cont...]
15 years, 12 months
[jBPM Development] - Injected hibernate SessionFactory is not used by jBPM 4.3?
by Guido Helmers
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.
Cheers,
Guido
+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.+
h3.
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@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:
ServiceLayerIntegrationTestModule
|
|__ 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:
@Provides
@Singleton
ProcessEngine provideProcessEngine(SessionFactory hibernateSessionFactory) {
return new Configuration().setResource("jbpm/jbpm.cfg.xml")
.setHibernateSessionFactory(hibernateSessionFactory).buildProcessEngine();
}
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
[http://community.jboss.org/message/536777#536777]
Start a new discussion in jBPM Development at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&cont...]
15 years, 12 months