19
This HowTo describes a way to integrate Seam, Spring and jBPM in order to use the same Hibernate SessionFactory in both Spring and jBPM (and of course, Seam).
At first, make sure you use the latest version 2.1.0 of Seam since you could get trouble with 2.0.1 and SpringTransactions.
The relevant parts of the configuration are:
- in your Spring bean config, define your Hibernate sessionFactory as usual and set the following properties in special
class=“…”>
<!– The hibernate properties –>
<property name=“hibernateProperties”>
<props>
…
<prop key=“hibernate.hbm2ddl.auto”>update</prop>
<!– set to create-drop to NOT maintain state between two executions of the app –>
<prop
key=“hibernate.transaction.flush_before_completion”>
true
</prop>
<prop key=“hibernate.connection.release_mode”>
after_transaction
</prop>
</props>
</property>
<!– this property must be set to false so we can use independent sessions –>
<property name=“useTransactionAwareDataSource”>
<value>false</value>
</property>
<property name=“mappingResources”>
<list>
<!– here you have to list all the *hbm.xml files for jBPM –>
<!– see the default hibernate.cfg.xml file from jBPM –>
…
</bean>
- second, for the Seam Spring integration we need two beans
class=“org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean”>
<property name=“sessionName” value=“hibernateSession” />
</bean>
<bean id=“localTransactionManager”
class=“org.springframework.orm.hibernate3.HibernateTransactionManager”>
<property name=“sessionFactory” ref=“hibernateSessionFactory” />
</bean>
That’s it for Spring configuration.
Now in components.xml, we need
<spring:spring-transaction platform-transaction-manager-name=“localTransactionManager”/>
<persistence:managed-hibernate-session name=“hibernateSession” auto-create=“true”
session-factory=“#{hibernateSessionFactory}”/>
<component class=“org.jboss.seam.bpm.Jbpm”>
<property name=“processDefinitions”>processdefinition.jpdl.xml</property>
</component>
In order to use the hibernateSession in jBPM, I subclassed the DbPersistenceService from jBPM. You need two classes:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.jboss.seam.Component;
import org.jboss.seam.contexts.Contexts;
import org.jbpm.svc.Service;
/**
* @author Frank Bitzer
*
*
*
*/
public class DbPersistenceServiceFactory extends
org.jbpm.persistence.db.DbPersistenceServiceFactory {
private static final long serialVersionUID = 997L;
SessionFactory sessionFactory;
/**
* {@inheritDoc}
*/
public Service openService() {
//create instance of own service implementation
return new your.namespace.jbpm.integration.DbPersistenceService(this);
}
/**
* Retrieve Hibernate sessionFactory
*/
@Override
public synchronized SessionFactory getSessionFactory() {
if (sessionFactory==null) {
if(Contexts.isApplicationContextActive()){
//access seam component holding session
Session session = (Session)
Component.getInstance(“hibernateSession”);
//and extract sessionFactory
sessionFactory = session.getSessionFactory();
}
}
return sessionFactory;
}
/**
* Set sessionFactory
*/
@Override
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
import org.hibernate.Session;
import org.jbpm.JbpmContext;
import org.jbpm.persistence.db.DbPersistenceServiceFactory;
import org.jbpm.svc.Services;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
/**
* @author Frank Bitzer
*
*
*
*/
public class DbPersistenceService extends
org.jbpm.persistence.db.DbPersistenceService {
private static final long serialVersionUID = 996L;
public DbPersistenceService(
DbPersistenceServiceFactory persistenceServiceFactory) {
this(persistenceServiceFactory, getCurrentServices());
}
static Services getCurrentServices() {
Services services = null;
JbpmContext currentJbpmContext = JbpmContext.getCurrentJbpmContext();
if (currentJbpmContext != null) {
services = currentJbpmContext.getServices();
}
return services;
}
DbPersistenceService(DbPersistenceServiceFactory persistenceServiceFactory,
Services services) {
super(persistenceServiceFactory);
this.persistenceServiceFactory = persistenceServiceFactory;
this.isTransactionEnabled = persistenceServiceFactory
.isTransactionEnabled();
this.isCurrentSessionEnabled = persistenceServiceFactory
.isCurrentSessionEnabled();
this.services = services;
}
/**
* Use Hibernate sessionFactory to retrieve a Session instance.
*/
public Session getSession() {
if ((session == null) && (getSessionFactory() != null)) {
session = getSessionFactory().openSession();
mustSessionBeClosed = true;
mustSessionBeFlushed = true;
mustConnectionBeClosed = false;
isTransactionEnabled = !SessionFactoryUtils.isSessionTransactional(
session, getSessionFactory());
if (isTransactionEnabled) {
beginTransaction();
}
}
return session;
}
}
To finish work, simply use the brand-new DbPersistenceService in jbpm.cfg.xml like
<jbpm-context>
<service name=“persistence”>
<factory>
<bean class=“your.namespace.jbpm.integration.DbPersistenceServiceFactory”>
<field name=“isTransactionEnabled”>
<false/>
</field>
</bean>
</factory>
</service>
…
</jbpm-context>
…
Also make sure your Spring WebApplicationContext is initialized before the startup of Seam. This can be achieved by placing the org.jboss.seam.servlet.SeamListener behind the listener for Spring in your web.xml.
That’s it! Now everything should work fine.
Note that I also contributed this HowTo to the official Seam Knowledge Base. You can find it here.
Related:
JDBC CommunicationsException with Hibernate and MySQL
IE blocks Cookies in iFrame - Solution for JSF/Seam
RichFaces: rich:modalPanel with rich:componentControl doesn’t show data
Are you interested in reading more from CodingClues?
Then subscribe to new postings
via RSS or
via
E-Mail.
Add New Comment
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Add New Comment
Trackbacks
(Trackback URL)