cancel
Showing results for 
Search instead for 
Did you mean: 

spring transaction support

hakanskucuk
Champ in-the-making
Champ in-the-making
We are currently using Jpa (Hibernate 3.6) and spring 3.0 in our project.
For automatic id generation we are using hibernate.id.enhanced.TableGenerator. To generate an id, hibernate fetches a new connection and do his work in this new connection and commits.

In spring integration examples, your are using  TransactionAwareDataSourceProxy. When we change DriverManagerDataSource to TransactionAwareDataSourceProxy, all the work is done in the same connection. Hibernate id generator does not get a new connection but commits. We can't rollback transactions because of id generator.

How can i solve this problem?

I think the problem mentioned in SPR-6839 is related with my problem.
in https://jira.springsource.org/browse/SPR-6839
4 REPLIES 4

hakanskucuk
Champ in-the-making
Champ in-the-making
Any answers? It blocks us to integrate activiti to our project.

frederikherema1
Star Contributor
Star Contributor
Have you tried using a "org.springframework.orm.hibernate.HibernateTransactionManager", it's javadoc states:

This transaction manager is appropriate for applications that use a single Hibernate SessionFactory for transactional data access, but it also supports direct DataSource access within a transaction (i.e. plain JDBC code working with the same DataSource). This allows for mixing services which access Hibernate and services which use plain JDBC (without being aware of Hibernate)! Application code needs to stick to the same simple Connection lookup pattern as with DataSourceTransactionManager (i.e. DataSourceUtils.getConnection(javax.sql.DataSource) or going through a TransactionAwareDataSourceProxy).

hakanskucuk
Champ in-the-making
Champ in-the-making
We are using org.springframework.orm.jpa.JpaTransactionManager.

Our spring configuration is below and it doesn't work. Should i change JpaTransactionManager to HibernateTransactionManager?

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

<bean id="dataSource"
  class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
  <property name="targetDataSource">
   <bean class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${hibernate.connection.driver_class}" />
    <property name="url" value="${hibernate.connection.url}" />
    <property name="username" value="${hibernate.connection.username}" />
    <property name="password" value="${hibernate.connection.password}" />
    <property name="defaultAutoCommit" value="false" />
   </bean>
  </property>
</bean>
  

<bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="persistenceUnitName" value="sparrow-jpa" />
  <property name="dataSource" ref="dataSource" />
  <property name="jpaDialect">
   <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
  </property>
  <property name="jpaVendorAdapter">
   <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="showSql" value="${hibernate.show_sql}" />
    <property name="generateDdl" value="${hibernate.generateDdl}" />
    <property name="databasePlatform" value="${hibernate.dialect}" />
   </bean>
  </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

      <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
  <property name="databaseType" value="mysql" />
  <property name="dataSource" ref="dataSource" />
  <property name="transactionManager" ref="transactionManager" />
  <property name="databaseSchemaUpdate" value="true" />
  <property name="jpaEntityManagerFactory" ref="entityManagerFactory" />
  <property name="jpaHandleTransaction" value="false" />
  <property name="jpaCloseEntityManager" value="false" />
  <property name="jobExecutorActivate" value="false" />
</bean>

       <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
  <property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>

frederikherema1
Star Contributor
Star Contributor
Hi,

The TransactionAwareDataSourceProxy we use, makes the connections Activiti uses, be aware of the active spring(jpa)-transaction, javadoc:

Proxy for a target JDBC DataSource, adding awareness of Spring-managed transactions. Similar to a transactional JNDI DataSource as provided by a J2EE server.

Data access code that should remain unaware of Spring's data access support can work with this proxy to seamlessly participate in Spring-managed transactions. Note that the transaction manager, for example DataSourceTransactionManager, still needs to work with the underlying DataSource, not with this proxy.

"Note that the transaction manager, for example DataSourceTransactionManager, still needs to work with the underlying DataSource, not with this proxy."

So the JPATransactionManager can be used, you should rig your EntityManagerFactory with the wrapped datasource instead of the proxied one, to make hibernate access fresh non-thread bound connections:
<bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${hibernate.connection.driver_class}" />
<property name="url" value="${hibernate.connection.url}" />
<property name="username" value="${hibernate.connection.username}" />
<property name="password" value="${hibernate.connection.password}" />
<property name="defaultAutoCommit" value="false" />
</bean>



<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="sparrow-jpa" />
<property name="dataSource" ref="dataSource" />


</bean>

<bean id="activitiDataSource"
class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<property name="targetDataSource" ref="dataSource">
</bean>



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



</bean>

Looks like our JPA examples use the proxied one, but our tests never fails since OpenJPA behaves nicely and is pleased with only one connection it seems Smiley Wink I'll make sure this is changed in 5.3 release.