Declaring Transactions , not working as desired
Hi,
My xml file is as shown below .
test-dao.xml :
Code:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>jdbc.properties</value>
</list>
</property>
</bean>
<bean id="localTestRepo" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
<!-- <property name="maxActive" value="10" />
<property name="initialSize" value="5" />
<property name="maxIdle" value="5" />
<property name="maxWait" value="10000" /> -->
</bean>
<!-- Hibernate Session Factory -->
<bean id="testSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource" ref="localTestRepo" />
<!-- <property name="lobHandler" ref="lobHandler"/> -->
<property name="mappingResources">
<list>
<value>test/test1.hbm.xml</value>
<value>test/test2.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
</props>
</property>
</bean>
<!-- Transactional Configs-->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory" ref="testSessionFactory" />
</bean>
<!-- Advice -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
<!-- <tx:method name="retrieve" propagation="REQUIRED" read-only="true" /> -->
</tx:attributes>
</tx:advice>
<!-- Advisor and pointcut -->
<aop:config>
<aop:advisor pointcut="execution(* com.equifax.test.dao.TestSaveInterface.saveRetrieve(..))" advice-ref="txAdvice"/>
</aop:config>
<!-- ************ --><!--
<tx:advice id="txAdvice" transaction-manager="transactionManager1">
<tx:attributes>
<tx:method name="wrap*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="aopTransactionBean" expression="execution(* com.equifax.aspire.persistence.AOPTransactionTestBean.*(...))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="aopTransactionBean"/>
</aop:config>
--><!-- ************ -->
<bean id="testDao" class="com.equifax.test.dao.BasicTestDao">
<property name="sessionFactory" ref="testSessionFactory" />
</bean>
</beans>
My class which tests the trasaction is as below.
code:
Code:
package com.equifax.test.dao;
public class TestSave implements TestSaveInterface{
BasicTestDao dao = (BasicTestDao)SpringContextHolder.ctx().getBean("testDao");
/**
* @param args
*/
public static void main(String[] args)
{
TestSave tsave = new TestSave();
SavableObject obj1 = new TestObj1();
SavableObject obj2 = new TestObj1();
obj1.setName("Robin");
obj1.setDesignation("Senior Analyst");
tsave.saveRetrieve(obj1, obj2);
}
public void saveRetrieve(SavableObject obj1, SavableObject obj2)
{
TestSave tsave = new TestSave();
tsave.save(obj1);
/*obj2 = (TestObj1) tsave.retrieve(new Long(23),obj2 );
System.out.println("result"+obj2.getDesignation());*/
}
public void save(SavableObject obj)
{
dao.save(obj);
Exception exception = new Exception();
try {
throw exception;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Object retrieve(Long id,Object obj)
{
return dao.findById(obj.getClass(), id);
}
}
As can be seen from the above class, Iam throwing an exception in the save method .In my xml file Iam defining advisor , for the save method to rollback on an Exception. My point cut definition is as in the above code. I was expecting that no value will be saved in the Db , as the trasaction will be roled back , but this is not happening . Is the trsactions not weaving? what is wrong with the above code? Is there some thing which Iam missing . I would appreciate any help on this.
thanks in advance!!!
The declarative trsaction management errors in spring
Mike,
I have corrected the 2 issues which you have pointed out, i.e. made the testSave a spring bean instead of instatiating , and have thrown the exception in the saveRetrieve method , instead of save method .
My testSave class now looks like this :
code:
[code]
public class TestSave implements TestSaveInterface{
BasicTestDao dao = (BasicTestDao)SpringContextHolder.ctx().getBean("t estDao");
public static TestSave tSave = (TestSave)SpringContextHolder.ctx().getBean("testS ave");
/**
* @param args
*/
public static void main(String[] args)
{
//TestSave tsave = new TestSave();
SavableObject obj1 = new TestObj1();
obj1.setName("Robin");
obj1.setDesignation("Senior Analyst");
try
{
tSave.saveRetrieve(obj1);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void saveRetrieve(SavableObject obj1) throws Exception
{
//TestSave tsave = new TestSave();
tSave.save(obj1);
// An exception is purposefully thrown
Exception exception = new Exception();
throw exception;
}
public void save(SavableObject obj)
{
dao.save(obj);
}
[\code]
the spring-config.xml is :
test-dao.xml
Code:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>jdbc.properties</value>
</list>
</property>
</bean>
<bean id="localTestRepo"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
<!-- <property name="maxActive" value="10" />
<property name="initialSize" value="5" />
<property name="maxIdle" value="5" />
<property name="maxWait" value="10000" /> -->
</bean>
<!-- Hibernate Session Factory -->
<bean id="testSessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource" ref="localTestRepo" />
<!-- <property name="lobHandler" ref="lobHandler"/> -->
<property name="mappingResources">
<list>
<value>test/test1.hbm.xml</value>
<value>test/test2.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
net.sf.hibernate.dialect.Oracle9Dialect
</prop>
</props>
</property>
</bean>
<!-- Transactional Configs-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory" ref="testSessionFactory" />
</bean>
<!-- Advice -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
<!-- <tx:method name="retrieve" propagation="REQUIRED" read-only="true" /> -->
</tx:attributes>
</tx:advice>
<!-- Advisor and pointcut -->
<aop:config>
<aop:advisor pointcut="execution(* com.equifax.test.dao.TestSaveInterface.saveRetrieve(..))" advice-ref="txAdvice"/>
</aop:config>
<!-- ************ -->
<bean id="testSave" class="com.equifax.test.dao.TestSave">
</bean>
<bean id="testDao" class="com.equifax.test.dao.BasicTestDao">
<property name="sessionFactory" ref="testSessionFactory" />
</bean>
</beans>
But, now when my springContextHolder class is trying to get a testSave Bean , Iam getting the following repeated message on my o/p console :
Code:
DEBUG 2008-01-25 10:13:14,288 [main] [net.sf.ehcache.CacheManager] Creating new CacheManager with default config
DEBUG 2008-01-25 10:13:14,319 [main] [net.sf.ehcache.CacheManager] Configuring ehcache from classpath.
WARN 2008-01-25 10:13:14,319 [main] [net.sf.ehcache.config.Configurator] No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/C:/InstalledSoftware/MavenLocalRepo/hibernate/ehcache/0.9/ehcache-0.9.jar!/ehcache-failsafe.xml
DEBUG 2008-01-25 10:13:14,319 [main] [net.sf.ehcache.config.Configuration$DiskStore] Disk Store Path: C:\DOCUME~1\rci1\LOCALS~1\Temp\
DEBUG 2008-01-25 10:13:15,490 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-25 10:13:16,145 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-25 10:13:16,723 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-25 10:13:17,238 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-25 10:13:17,721 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-25 10:13:18,174 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-25 10:13:18,658 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-25 10:13:19,204 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-25 10:13:19,625 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-25 10:13:20,062 [main] [net.sf.ehcache.CacheManager] Attempting to create an existing instance. Existing instance returned.
DEBUG 2008-01-2
spring context Holder class :
Code:
public final class SpringContextHolder
{
private static ApplicationContext springCtx;
private static ApplicationContext webAppSpringCtx;
private Map ctxs = new HashMap();
private static SpringContextHolder instance = null;
private SpringContextHolder()
{
}
public static final synchronized ApplicationContext ctx()
{
if (SpringContextHolder.springCtx == null)
{
SpringContextHolder.springCtx = new ClassPathXmlApplicationContext(new String[] { "test/test-dao.xml" });
}
return SpringContextHolder.springCtx;
}
public static SpringContextHolder getInstance()
{
if (SpringContextHolder.instance == null)
{
SpringContextHolder.instance = new SpringContextHolder();
}
return SpringContextHolder.instance;
}
}
What may be going wrong , when the Spring container is trying to get an instance of my bean ?
thanks in advance!!!