Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

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

<bean id="hibernateSessionFactory"
                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

<bean id="sessionFactory"
                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

<!-- use the power of Spring transactions -->
<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:

package your.namespace.jbpm.integration;



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
 * 
 * EL4J - The Extension Library for Java.
 *
 */

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;
          }
        
        
}
package your.namespace.jbpm.integration;

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
 * 
 * EL4J - The Extension Library for Java.
 *
 */
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.

Cheers,

Frank Bitzer, just works! Software diet pills Affordable Degree Education Degree Online Degree adipex