cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti with Hibernate

cookie-exploit
Champ in-the-making
Champ in-the-making
Hello guys,

is it possible to use Activiti with hibernate instead of mybatis? And if it is possible, what I have to do to make it work?


Greetz cookie-exploit
11 REPLIES 11

frederikherema1
Star Contributor
Star Contributor
You'll have to replace the whole internals of activiti for this (alls sessions/managers and their factories), so it's possible but I guess it will take a *very* long time to do, possibly having to change a few bits here and there in the layers above. So my advice would be: don't do it Smiley Wink

What's the use-case for using hibernate?

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
Probably some 'architect' or 'it manager' requires it.

cookie-exploit
Champ in-the-making
Champ in-the-making
First of all, thanks for replies. Smiley Happy

The case is that we actually use hibernate and jbpm in our project and we not really want to use a lot of different frameworks, so it's would be nice to use hibernate.
Now I had to talk with my project leader that it would be a long way to use activiti with hibernate and that he should think about to use myBatis.

Another Question: What was the intention to use for activiti myBatis instead of hibernate? Are there any benefits of myBatis over hibernate?


EDIT: I forgot another important point, we actually use a single hibernate session for our persistence and jbpm persistence. That's a big problem, because we need this features.

bernd_ruecker
Champ in-the-making
Champ in-the-making
Hi.

You could still use the datasource in MyBatis, so technically there is no real disadvantage. The reason basically was:
- Hibernate is LGPL, we want to have only ASL license dependencies -> Hibernate not possible
- JPA would have been possible, BUT
  - MyBatis turned out to be much more flexible. we can do a lot of tweaking and tuning behind the scenes. See for example http://www.jorambarrez.be/blog/2012/06/28/the-activiti-performance-showdown/, some of the improvements we did would not have been easily possible with JPA. Or take https://app.camunda.com/confluence/display/foxUserGuide/fox+cockpit, where we can click together sophisticated queries, we actually tried this with JPA, but MyBatis turned out to be waaaay easier. Last but not least Hibernate even caused some trouble with DB2-XA drivers, stuff you can easily fix on the MyBatis level, so I am pretty happy with myBatis at this moment.
  - And since we do not have a typical business application with a lot of entities, the pain of writing XML mappings is not that big.

Does this explain MyBatis? Till now that was never a showstopper in the projects.

Cheers
Bernd

nandoztx
Champ in-the-making
Champ in-the-making
I am having the same problem that you, about the session of Hiberate.
I need to use a single Hibernate session, and with activiti, i am not able to do this.  Smiley Sad

cookie-exploit
Champ in-the-making
Champ in-the-making
I have solved the problem for our needs.

Now Activiti uses the HibernateTransactionManager and with that we can make a full rollback! Its not important that Activiti uses MyBatis, because after a small research about MyBatis I found out that MyBatis support the HibernateTransactionManager.

ApplicationCotext:

<!– DataSource Definition –>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/activiti"/>
<property name="username" value="root" />
<property name="password" value="root" />
<property name="poolPreparedStatements" value="true" />
<property name="maxActive" value="50" />
<property name="maxIdle" value="10" />
</bean>

<!– Session Factory Definition –>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
  <ref bean="dataSource" />
</property>

</bean>


<!– Hibernate Transaction Manager Definition –>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
  <ref local="sessionFactory" />
</property>
<property name="dataSource">
  <ref local="dataSource" />
</property>
</bean>

<!– Process Engine Definition –>
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
</bean>

Methods for start and commit a transation (all Transactions done after startTransaction are commit after call commit Transaction):

protected TransactionStatus startTransaction() {
PlatformTransactionManager manager = getTransactionManager();
DefaultTransactionDefinition d = new DefaultTransactionDefinition();
d.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW);

transaction = manager.getTransaction(d);

return transaction;
}

protected void commit(TransactionStatus transaction) {
PlatformTransactionManager manager = getTransactionManager();
manager.commit(transaction);
}

protected void rollback(TransactionStatus transaction) {
PlatformTransactionManager manager = getTransactionManager();
manager.rollback(transaction);
}

private PlatformTransactionManager getTransactionManager() {

return (PlatformTransactionManager) this.appContext
   .getBean("transactionManager");
}

I hope this helps anyone who have a problem to integrate activiti in a hibernate environment.

P.S.: I think it would be great if this method (or something like that) is also found in the activiti doucumentation, because lots of projects currently using hibernate for persitences and in the activit documentation doesn't exist a guide to integrate activiti in an hibernate environment.

nandoztx
Champ in-the-making
Champ in-the-making
Hi cookie-exploit,

I have no idea where to put these implementations commit and rollback.
Could be a little more specific?

Thanks.

cookie-exploit
Champ in-the-making
Champ in-the-making
You could think about a class which offers these implementations and all of your beans for extends these class.
Then if you call a specific Method in the bean e.g. bean.save() which call commit() after do some stuff or bean.onError() if an error occurs an the it call rollback().


public class MyBean() extends BaseAction{
private MyObject pojo;
private MyService service;
private RuntimeService runtimeService;


public void doSomeStuff() {
  pojo.setText("demo");
  pojo.setValue(42);
 
  save(); // Or just call the save from your GUI for example
}


public void save() {
  try {
   service.save(pojo);
   runtimeService.setVariable(pInst.getId(), "pojoid", pojo.getId());
 
   commit();
  }
  catch(Exception e) {
   onError(e);
  }
}


public void onError(Exception e) {
  // do some stuff
 
  rollback();
}

}

I hope you now understand how to use this methods, otherwise ask! Smiley Happy


Greets cookie-exploit

nandoztx
Champ in-the-making
Champ in-the-making
Thanks for you reply, but i don't understand yet =/
I don't use spring like that, so i use:

applicationContext.xml:

<bean id="dataSource"
    class="com.mchange.v2.c3p0.ComboPooledDataSource">
      <property name="driverClass" value="${database.driver}" />
      <property name="jdbcUrl" value="${database.url}" />
      <property name="user" value="${database.username}" />
      <property name="password" value="${database.password}" />
      <property name="initialPoolSize" value="3" />
      <property name="minPoolSize" value="1" />
      <property name="maxPoolSize" value="17" />
  </bean>

<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="dataSource" ref="dataSource" />
    <property name="sessionFactory" ref="sessionFactory" />
  </bean>

<bean
    class="org.springframework.transaction.aspectj.AnnotationTransactionAspect"
    factory-method="aspectOf">
    <property name="transactionManager">
      <ref local="transactionManager" />
    </property>
  </bean>

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    <property name="databaseType" value="postgres" />
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="transactionManager" />


and to open a transaction so i use:

   @Override
@Transactional
public ProcessInstance startWorkflowProcess(String processDefinitionId, Map<String, Object> variables, String currentUser){
  log.debug("Starting new process with the id: "+processDefinitionId+" and the variables are :"+variables);
  identityService.setAuthenticatedUserId(currentUser);
  ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, variables);
  identityService.setAuthenticatedUserId(null);
 
  return processInstance;
}

The only thing that i use to manage my transactions is this:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class JPASessionFactory {

@Autowired
private SessionFactory sessionFactory;

public Session getCurrentSession() {
  return sessionFactory.getCurrentSession();
}

public SessionFactory getSessionFactory() {
  return sessionFactory;
}
}

Thank you!