Franklin Antony [
http://community.jboss.org/people/frankee787] created the discussion
"Re: In memory TaskClient without Mina or JMS"
To view the discussion, visit:
http://community.jboss.org/message/617173#617173
--------------------------------------------------------------
First of all, thanks a lot for all the help especially Daniele Ulrich for the patched
files. After 10-12 hours night out slogging, following are my findings.
Only the patched files(jbpm-human-task-jpa-5.0.0-patched.jar) work with JTA and the
default (jbpm-human-task-5.0.0.jar) doesnt work saying *java.lang.IllegalStateException: A
JTA EntityManager cannot use getTransaction()*
*
*
Hence I would humbly as the authors of jBPM5 to reconsider the option of making the
TaskServiceSession support JTA transactions as well.
I have been able to support the following usecase with the *Bitronix JTA implementation.*
*
*
The main serivce class is MainService
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainService implements IMainService {
IBusinessProcessService jbpmService;
IBusinessProcessService ourService;
public IBusinessProcessService getJbpmService() {
return jbpmService;
}
public void setJbpmService(IBusinessProcessService jbpmService) {
this.jbpmService = jbpmService;
}
public IBusinessProcessService getOurService() {
return ourService;
}
public void setOurService(IBusinessProcessService ourService) {
this.ourService = ourService;
}
public static void main(String[] args)
{
ClassPathXmlApplicationContext cp = new ClassPathXmlApplicationContext(new
String[]{"jBPM-layer.xml","dao-layer.xml"});
IMainService mainService =
(IMainService)cp.getBean("mainService");
mainService.doThis();
}
public void doThis()
{
getOurService().createTask(null);
getJbpmService().createTask(null);
getOurService().createTask(null);
getJbpmService().createTask(null);
if(1==1)
{
throw new RuntimeException();
}
}
}
As can be seen the MainService is something like a façade which calls two other service.
One creates a record in the application database(getOurService()) and the other
(getJbpmService()) creates a task/user inside the jBPM database. I have been trying to
transactionalize this for quite sometime but in vain. However now its possible , but again
only with the patched files.
This is ourService TXNJBPMServiceImp. Although the class name says JBPM, it has nothing to
do with jBPM . Just a copy paste of a class …was so tired to give even a proper name. So,
basically this is our application service which inserts a dummy testUser record in our
application database.
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.apache.log4j.Logger;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TXNJBPMServiceImp implements IBusinessProcessService{
private static Logger log = Logger.getLogger(TXNJBPMServiceImp.class);
private EntityManagerFactory entityManagerFactory;
public EntityManagerFactory getEntityManagerFactory() {
return entityManagerFactory;
}
public void setEntityManagerFactory(EntityManagerFactory
entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
public static void main(String[] args)
{
}
@Override
public BPMTaskResponse createTask(Task task) {
System.out.println("Creating...Task!!");
EntityManager em =
getEntityManagerFactory().createEntityManager();
TestUser testUser = new TestUser();
testUser.setName("TXNJBPMServiceImp");
//em.getTransaction().begin();
em.persist(testUser);
//em.getTransaction().commit();
System.out.println("Creating...Task DONE!!");
return null;
}
}
Next comes the actual jBPM service which now just creates a user in the jBPM database. As
can be seen, it does nothing great. It just hacks into jBPM and gets a taskSession and
creates a user. You can use the same taskSession and create Tasks, claim them, complete
them etc.
import java.util.List;
import javax.persistence.EntityManagerFactory;
import org.apache.log4j.Logger;
import org.drools.SystemEventListenerFactory;
import org.jbpm.task.service.TaskService;
import org.jbpm.task.service.TaskServiceSession;
public class FinalTXNJBPMServiceImp implements IBusinessProcessService{
private static Logger log =
Logger.getLogger(FinalTXNJBPMServiceImp.class);
public TaskServiceSession getTaskSession()
{
return getTaskService().createSession();
}
public TaskService getTaskService() {
return new TaskService(getEntityManagerFactory(),
SystemEventListenerFactory.getSystemEventListener());
}
private EntityManagerFactory entityManagerFactory;
public EntityManagerFactory getEntityManagerFactory() {
return entityManagerFactory;
}
public void setEntityManagerFactory(EntityManagerFactory
entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
public static void main(String[] args)
{
}
@Override
public BPMTaskResponse createTask(Task task) {
TaskService taskService = new TaskService(getEntityManagerFactory(),
SystemEventListenerFactory.getSystemEventListener());
TaskServiceSession taskSession = taskService.createSession();
org.jbpm.task.User aUser = new org.jbpm.task.User();
aUser.setId("DELNOW2");
taskSession.addUser(aUser);
System.out.println("Creating...Task DONE!!");
return null;
}
}
Almost there. Now the spring configuration file.
<?xml version=+"1.0"+ encoding=+"UTF-8"+?>
<beans
xmlns=+"http://www.springframework.org/schema/beans"+
xmlns:xsi=+"http://www.w3.org/2001/XMLSchema-instance"+
xmlns:context=+"http://www.springframework.org/schema/context"+
xsi:schemaLocation=+"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd+
+
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/context/spring-context.xsd"+>
<context:property-placeholder location=+"classpath:jdbc.properties"+/>
<bean id=+"mainServiceRef"+
class=+"ae.emaratech.em.bpm.jbpm.MainService"+ >
<property name=+"jbpmService"+
ref=+"finalbusinessProcessServiceRef"+></property>
<property name=+"ourService"+
ref=+"businessProcessServiceRef"+></property>
</bean>
<bean id=+"mainService"+
class=+"org.springframework.transaction.interceptor.TransactionProxyFactoryBean"+>
<property name=+"transactionManager"+ ref=+"JtaTransactionManager"+
/>
<property name=+"transactionAttributes"+>
<props>
<prop key=+"*"+>PROPAGATION_REQUIRED, -Exception</prop>
</props>
</property>
<property name=+"target"+ ref=+"mainServiceRef"+ />
</bean>
<context:annotation-config/>
<bean id=+"JtaTransactionManager"+
class=+"org.springframework.transaction.jta.JtaTransactionManager"+ >
<property name=+"transactionManager"+
ref=+"BitronixTransactionManager"+ />
<property name=+"userTransaction"+
ref=+"BitronixTransactionManager"+ />
</bean>
<bean id=+"btmConfig"+ factory-method=+"getConfiguration"+
class=+"bitronix.tm.TransactionManagerServices"+>
<property name=+"serverId"+ value=+"spring-btm"+ />
</bean>
<!-- create BTM transaction manager -->
<bean id=+"BitronixTransactionManager"+
factory-method=+"getTransactionManager"+
class=+"bitronix.tm.TransactionManagerServices"+
depends-on=+"btmConfig"+ destroy-method=+"shutdown"+ />
<bean id=+"finalbusinessProcessService"+
class=+"org.springframework.transaction.interceptor.TransactionProxyFactoryBean"+>
<property name=+"transactionManager"+ ref=+"JtaTransactionManager"+
/>
<property name=+"transactionAttributes"+>
<props>
<prop key=+"*"+>PROPAGATION_REQUIRED, -Exception</prop>
</props>
</property>
<property name=+"target"+ ref=+"finalbusinessProcessServiceRef"+
/>
</bean>
<bean id=+"finalbusinessProcessServiceRef"+
class=+"ae.emaratech.em.bpm.jbpm.FinalTXNJBPMServiceImp"+ >
<property name=+"entityManagerFactory"+
ref=+"entityManagerFactory"+/>
</bean>
<bean id=+"businessProcessService"+
class=+"org.springframework.transaction.interceptor.TransactionProxyFactoryBean"+>
<property name=+"transactionManager"+ ref=+"JtaTransactionManager"+
/>
<property name=+"transactionAttributes"+>
<props>
<prop key=+"*"+>PROPAGATION_REQUIRED, -Exception</prop>
</props>
</property>
<property name=+"target"+ ref=+"businessProcessServiceRef"+ />
</bean>
<bean id=+"businessProcessServiceRef"+
class=+"ae.emaratech.em.bpm.jbpm.TXNJBPMServiceImp"+ >
<property name=+"entityManagerFactory"+
ref=+"ourEntityManagerFactory"+/>
</bean>
<bean id=+"userInfoImp"+
class=+"ae.emaratech.em.bpm.jbpm.DBUserInfoImp"+>
<property name=+"userDAO"+ ref=+"userDAO"+ />
</bean>
<bean id=+"entityManagerFactory"+
class=+"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"+
depends-on=+"btmConfig"+>
<property name=+"persistenceUnitName"+
value=+"org.jbpm.task"+></property>
<property name=+"dataSource"+ ref=+"jBPMDataSource"+/>
<property name=+"persistenceXmlLocation"+
value=+"classpath:META-INF/persistence.xml"+ />
<property name=+"jpaVendorAdapter"+>
<bean
class=+"org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"+>
<property name=+"database"+ value=+"MYSQL"+ />
<property name=+"showSql"+ value=+"true"+ />
<property name=+"databasePlatform"+
value=+"org.hibernate.dialect.MySQL5InnoDBDialect"+/>
</bean>
</property>
</bean>
<bean id=+"ourEntityManagerFactory"+
class=+"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"+
depends-on=+"btmConfig"+>
<property name=+"persistenceUnitName"+
value=+"ourUnit"+></property>
<property name=+"dataSource"+ ref=+"ourDataSource"+/>
<property name=+"persistenceXmlLocation"+
value=+"classpath:META-INF/persistence.xml"+ />
<property name=+"jpaVendorAdapter"+>
<bean
class=+"org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"+>
<property name=+"database"+ value=+"MYSQL"+ />
<property name=+"showSql"+ value=+"true"+ />
<property name=+"databasePlatform"+
value=+"org.hibernate.dialect.MySQL5InnoDBDialect"+/>
<property name=+"generateDdl"+ value=+"true"+/>
</bean>
</property>
</bean>
<!-- Bitronix Transaction Manager embedded configuration -->
<bean id=+"jBPMDataSource"+
class=+"bitronix.tm.resource.jdbc.PoolingDataSource"+
init-method=+"init"+ destroy-method=+"close"+>
<property name=+"uniqueName"+ value=+"java/jbpmdb"+ />
<property name=+"maxPoolSize"+ value=+"5"+ />
<property name=+"minPoolSize"+ value=+"0"+ />
<property name=+"driverProperties"+>
<props>
<prop key=+"user"+>${jdbc.jbpm.username}</prop>
<prop key=+"password"+>${jdbc.jbpm.password}</prop>
<prop key=+"url"+>${jdbc.jbpm.url}</prop>
</props>
</property>
<property name=+"className"+
value=+"com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"+ />
<property name=+"allowLocalTransactions"+ value=+"false"+ />
<property name=+"enableJdbc4ConnectionTest"+
value=+"true"+/>
</bean>
<!-- Bitronix Transaction Manager embedded configuration -->
<bean id=+"ourDataSource"+
class=+"bitronix.tm.resource.jdbc.PoolingDataSource"+
init-method=+"init"+ destroy-method=+"close"+>
<property name=+"uniqueName"+ value=+"java/emdb"+ />
<property name=+"minPoolSize"+ value=+"0"+ />
<property name=+"maxPoolSize"+ value=+"5"+ />
<property name=+"driverProperties"+>
<props>
<prop key=+"user"+>${jdbc.emdb.username}</prop>
<prop key=+"password"+>${jdbc.emdb.password}</prop>
<prop key=+"url"+>${jdbc.emdb.url}</prop>
</props>
</property>
<property name=+"className"+
value=+"com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"+ />
<property name=+"allowLocalTransactions"+ value=+"false"+ />
<property name=+"enableJdbc4ConnectionTest"+ value=+"true"+/>
</bean>
</beans>
And finally the persistence.xml file.
<?xml version=+"1.0"+ encoding=+"UTF-8"+
standalone=+"yes"+?>
<persistence version=+"1.0"+
xsi:schemaLocation=+"
http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd+
+http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"+
xmlns:orm=+"
http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm"+
xmlns:xsi=+"
http://www.w3.org/2001/XMLSchema-instance
http://www.w3.org/2001/XMLSchema-instance"+
xmlns=+"
http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence"+>
<persistence-unit name=+"org.jbpm.task"+
transaction-type=+"JTA"+>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>META-INF/orm.xml</mapping-file>
<class>org.jbpm.task.Attachment</class>
<class>org.jbpm.task.Content</class>
<class>org.jbpm.task.BooleanExpression</class>
<class>org.jbpm.task.Comment</class>
<class>org.jbpm.task.Deadline</class>
<class>org.jbpm.task.Comment</class>
<class>org.jbpm.task.Deadline</class>
<class>org.jbpm.task.Delegation</class>
<class>org.jbpm.task.Escalation</class>
<class>org.jbpm.task.Group</class>
<class>org.jbpm.task.I18NText</class>
<class>org.jbpm.task.Notification</class>
<class>org.jbpm.task.EmailNotification</class>
<class>org.jbpm.task.EmailNotificationHeader</class>
<class>org.jbpm.task.PeopleAssignments</class>
<class>org.jbpm.task.Reassignment</class>
<class>org.jbpm.task.Status</class>
<class>org.jbpm.task.Task</class>
<class>org.jbpm.task.TaskData</class>
<class>org.jbpm.task.SubTasksStrategy</class>
<class>org.jbpm.task.OnParentAbortAllSubTasksEndStrategy</class>
<class>org.jbpm.task.OnAllSubTasksEndParentEndStrategy</class>
<class>org.jbpm.task.User</class>
<class>org.drools.persistence.info.SessionInfo</class>
<class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
<class>org.jbpm.persistence.processinstance.ProcessInstanceEventInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name=+"hibernate.connection.autocommit"+ value=+"false"+
/>
<property name=+"hibernate.hbm2ddl.auto"+ value=+"validate"+ />
<property name=+"hibernate.max_fetch_depth"+ value=+"3"+/>
<property name=+"hibernate.show_sql"+ value=+""+ />
<property name=+"hibernate.transaction.manager_lookup_class"+
value=+"org.hibernate.transaction.BTMTransactionManagerLookup"+/>
</properties>
</persistence-unit>
<persistence-unit name=+"ourUnit"+ transaction-type=+"JTA"+>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>ae.emaratech.em.bpm.jbpm.TestUser</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name=+"hibernate.connection.autocommit"+ value=+"false"+
/>
<property name=+"hibernate.hbm2ddl.auto"+ value=+"validate"+ />
<property name=+"hibernate.max_fetch_depth"+ value=+"3"+/>
<property name=+"hibernate.show_sql"+ value=+""+ />
<property name=+"hibernate.transaction.manager_lookup_class"+
value=+"org.hibernate.transaction.BTMTransactionManagerLookup"+/>
</properties>
</persistence-unit>
</persistence>
Few notes. After changing to the patched jBPM files, the orm.xml throws error while trying
to be passed. You will have to change references to “Task” in queries to
“org.jbpm.task.Task”. Likewise all other objects such as I18NText, OrganizationalEntity
etc.
--------------------------------------------------------------
Reply to this message by going to Community
[
http://community.jboss.org/message/617173#617173]
Start a new discussion in jBPM at Community
[
http://community.jboss.org/choose-container!input.jspa?contentType=1&...]