-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: Spring+Hibernate+Mysql Innodb transaction rollback problem
PostPosted: Wed Nov 19, 2003 8:13 am 
Beginner
Beginner

Joined: Tue Nov 18, 2003 10:16 am
Posts: 33
Location: Cluj-Napoca, Romania
I am trying to use a declarative transaction management provided by Spring framework.
My Test class is calling two methods from CategoryDAO bean class: an insert first and then an get.
Method get is throwing an exception, but the insert is not rolledback.

I have to mention that the transactions are working in Mysql InnoDB tables (I have checked this).
This test is working properly when no exception is thrown.
If setting show_sql property on true, for each method call , hibernate is seems to create a new connection. This is the message at the console:

[i]Nov 19, 2003 1:14:16 PM org.springframework.jdbc.datasource.DriverManagerDataSource getConnectionFromDriverManager
INFO: Creating new JDBC connection to [jdbc:mysql://localhost:3306/forum][/i]


As far as I know, a transaction with jdbc must take place within one single connection. In this case, it said that 2 connections are created.
Maybe this is the problem?

Many thanks,
Florin Marcus

ServiceBean:
[code]....
public void saveCategory(Category category) throws Exception
{
getHibernateTemplate().saveOrUpdate(category);
}

public Category getCategory(Long categoryId) throws Exception
{
this.getHibernateTemplate();
return (Category)this.getHibernateTemplate().load(ro.gebs.forum.db.Category.class, categoryId);
} // end get method[/code]
Test client:

[code] public static void main(String[] args) throws Exception
{
FileSystemXmlApplicationContext ctx = null;

try {
ctx = new FileSystemXmlApplicationContext("applicationContext-hibernate.xml");
} catch (IOException e) {
e.printStackTrace();

CategoryDAO bean = (CategoryDAO) (ctx.getBean("targetService"));


bean.saveCategory(new Category( "new category"));
//this call is throwing an Exception
bean.getCategory(new long(1000));

}[/code]
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 9:34 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
It is not clear where the transaction demarcation is so if indeed it is starting two transactions then yes this is your problem. The first was already commited.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 10:01 am 
Beginner
Beginner

Joined: Tue Nov 18, 2003 10:16 am
Posts: 33
Location: Cluj-Napoca, Romania
But this is exactly what I don't want to do: to create two transactions instead of one.
My Interceptor and DAO configuration looks like this:


Code:
<bean id="clinic" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
      <property name="transactionManager"><ref local="transactionManager"/></property>
        <property name="target"><ref local="targetService"/></property>
      <property name="transactionAttributes">
         <props>
            <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
         </props>
      </property>
   </bean>


   <bean id="targetService" class="ro.gebs.forum.dao.CategoryDAO">
      <property name="sessionFactory"><ref local="sessionFactory"/></property>
   </bean>



May thanks


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2003 10:52 am 
Senior
Senior

Joined: Wed Aug 27, 2003 6:04 am
Posts: 161
Location: Linz, Austria
Your transactional proxy will create a transaction for each method invocation of the target object. You are calling two methods of your DAO, therefore each of them will properly be executed in its own transaction. The same happens when you use an SLSB: Each method invocation will be executed in its own transaction.

If you want to execute multiple method calls within the same transaction, you need to demarcate that. A typical way of doing this is to create a transactional proxy for your high-level business service instead of for your DAO. Each business service method will then get executed in its own transaction, being able to call as many DAO methods in it as needed.

You can also demarcate such high-level transactions programmatically, via TransactionTemplate (or PlatformTransactionManager directly):

Code:
ctx = new FileSystemXmlApplicationContext("applicationContext-hibernate.xml");
PlatformTransactioManager tm = (PlatformTransactionManager) ctx.getBean("transactionManager");
final CategoryDAO bean = (CategoryDAO) (ctx.getBean("targetService"));

TransactionTemplate tt = new TransactionTemplate(tm);
tt.execute(new TransactionCallbackWithoutResult() {
  public void doInTransactionWithoutResult(TransactionStatus status) {
    bean.saveCategory(new Category( "new category"));
    bean.getCategory(new long(1000));
  }
});


Juergen


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2003 5:27 am 
Beginner
Beginner

Joined: Tue Nov 18, 2003 10:16 am
Posts: 33
Location: Cluj-Napoca, Romania
I have created a higher lever for business in which I am calling 2 methods from DAO.
I have mapped the transactional proxy as suggested.
Still the same result. Two connections are created instead of one.

I know about TransactionTemplate and I have succeded to implement it properly. But I want to use declarative transaction demarcation.
Here is the entire aplicationContext.xml file config I use

Code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<!-- ========================= Start of PERSISTENCE DEFINITIONS ========================= -->

<!-- NOTE: Choose exactly 1 "dataSource" bean and 1 dialect for the "sessionFactory" -->

<!-- Local MySQL DataSource that works in any environment -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
  <property name="url"><value>jdbc:mysql://localhost:3306/forum</value></property>
  <property name="username"><value>root</value></property>
  <property name="password"><value></value></property>
</bean>

<!-- Hibernate SessionFactory for HSQL or MySQL -->
<!-- Choose the dialect that matches your "dataSource" definition -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
  <property name="dataSource"><ref local="dataSource"/></property>
  <property name="mappingResources">
            <value>category.hbm.xml</value>
  </property>
  <property name="hibernateProperties">
   <props>
                <!--
    <prop key="hibernate.dialect">net.sf.hibernate.dialect.HSQLDialect</prop>
    -->
    <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
   </props>
  </property>
</bean>

<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
  <property name="sessionFactory"><ref local="sessionFactory"/></property>
        <property name="dataSource"><ref local="dataSource"/></property>
</bean>

<!-- Transaction manager that delegates to JTA (for a transactional JNDI DataSource) -->
<!--
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
-->

<!-- Transactional proxy for the Forum primary business object -->
<bean id="clinic" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager"><ref local="transactionManager"/></property>
        <property name="target"><ref local="forumTarget"/></property>
  <property name="transactionAttributes">
   <props>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="test">PROPAGATION_REQUIRED</prop>
   </props>
  </property>
</bean>

  <bean id="categoryDAO" class="ro.gebs.forum.bm.CategoryDAO">
  <property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>

    <!--service method -->
    <bean id="forumTarget" class="ro.gebs.forum.bm.ServiceCategory">
        <property name="transactionManager"><ref local="transactionManager"/></property>
   
    <!--  dao object -->
      <property name="categoryDAO">
          <ref bean="categoryDAO"/>
        </property>
      </bean>

<!-- ========================= End of PERSISTENCE DEFINITIONS ========================= -->

</beans>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 20, 2003 12:16 pm 
Senior
Senior

Joined: Wed Aug 27, 2003 6:04 am
Posts: 161
Location: Linz, Austria
This should work as long as you're accessing the proxy (BTW, you might want to rename it from "clinic" to "forum") and not "forumTarget" itself. Else, you'd invoke the methods on the target object directly instead of going through the transactional proxy.

Furthermore, the names of your transactional methods need to match the patterns specified as "transactionAttributes", i.e. "get*", "find*", "load*", or "test" in your case.

Juergen


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 21, 2003 6:15 am 
Beginner
Beginner

Joined: Tue Nov 18, 2003 10:16 am
Posts: 33
Location: Cluj-Napoca, Romania
I have finally understand the meaning of proxy.
For my Service Object I didn't had an inteterface to implement.
Now it works.

Thanks again.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.