amd700
Dec 6th, 2004, 03:37 AM
Hi all,
I have encountered a problem when using Spring Transaction Management feature.
The following sources are based on the example petClinic sources.
But the TransactionProxyFactoryBean seem go wrong (maybe) when I intentionally throw a DataAccessException in storeComposite method.
The transaction still commit instead rollback.
Please help me. Thank you
--------- composite.hbm.xml -----------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hib...g-2.0.dtd">
<hibernate-mapping auto-import="true">
<class name="example.framework.model.CompositeModel" table="Composite">
<id name="id" type="int" unsaved-value="-1">
<generator class="assigned"/>
</id>
<set name="children" lazy="false" cascade="all">
<key column="parent_id"/>
<one-to-many class="example.framework.model.CompositeModel"/>
</set>
<property name="parentId" column="parent_id" type="java.lang.Integer"/>
<property name="name" type="java.lang.String"/>
<property name="description" type="java.lang.String"/>
</class>
</hibernate-mapping>
----------------jdbc.properties ---------------
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://localhost:9001
jdbc.username=sa
jdbc.password=
hibernate.dialect=net.sf.hibernate.dialect.HSQLDia lect
----------------- applicationContext.xml -----------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/s...beans.dtd">
<beans>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyP laceholderConfigurer">
<property name="location"><value>jdbc.properties</value></property>
</bean>
<!-- Local DataSource that works in any environment -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerD ataSource">
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
<property name="url"><value>${jdbc.url}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFact oryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<value>composite.hbm.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransac tionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="compositeTarget" class="example.framework.persistent.CompositePMImpl">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="proxy" class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean">
<property name="transactionManager"><ref local="transactionManager"/></property>
<property name="target"><ref local="compositeTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="store*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
------------- CompositeModel.java --------------------
package example.framework.model;
import java.util.Iterator;
import java.util.Set;
public class CompositeModel {
private int m_nId = 0;
private int m_nParentId = 0;
private String m_sName = null;
private String m_sDescription = null;
private CompositeModel m_parent = null;
private Set m_children = null;
public int getId() {
return m_nId;
}
public void setId(int m_nId) {
this.m_nId = m_nId;
}
public int getParentId() {
return m_nParentId;
}
public void setParentId(int m_nParentId) {
this.m_nParentId = m_nParentId;
}
public String getName() {
return m_sName;
}
public void setName(String m_sName) {
this.m_sName = m_sName;
}
public String getDescription() {
return m_sDescription;
}
public void setDescription(String m_sDescription) {
this.m_sDescription = m_sDescription;
}
public CompositeModel getParent() {
return m_parent;
}
public void setParent(CompositeModel m_parent) {
this.m_parent = m_parent;
}
public Set getChildren() {
return m_children;
}
public void setChildren(Set m_children) {
this.m_children = m_children;
}
public String toString() {
final StringBuffer buf = new StringBuffer();
buf.append("CompositeModel");
buf.append("\n\tm_nId=").append(m_nId);
buf.append("\n\tm_nParent=").append(m_nParentId);
buf.append("\n\tm_sName=").append(m_sName);
buf.append("\n\tm_sDescription=").append(m_sDescription);
buf.append("\n\tm_parent=").append(m_parent == null ? null : m_parent.toString());
Set children = getChildren();
if (children == null)
buf.append("\n\tHas no children");
else {
buf.append("\n\tNumber of children = " + children.size());
buf.append("\n\t{");
for (Iterator i = children.iterator(); i.hasNext();) {
CompositeModel com = (CompositeModel) i.next();
buf.append(com.toString());
}
buf.append("\n\t}");
}
buf.append("\n\t------------------");
return buf.toString();
}
}
---------CompositePM---------------
package example.framework.persistent;
import example.framework.model.CompositeModel;
import org.springframework.dao.DataAccessException;
import java.util.List;
public interface CompositePM {
public List listComposite();
public CompositeModel findComposite(int nId);
public void storeComposite(CompositeModel composite) throws DataAccessException;
public void updateComposite(CompositeModel composite) throws DataAccessException;
public void deleteComposite(CompositeModel composite) throws DataAccessException;
}
------CompositePMImpl---------------
package example.framework.persistent;
import example.framework.model.CompositeModel;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate.support.Hibernat eDaoSupport;
import java.util.List;
public class CompositePMImpl extends HibernateDaoSupport implements CompositePM {
public List listComposite() {
return getHibernateTemplate().find("from CompositeModel AS composite");
}
public CompositeModel findComposite(int nId) {
return (CompositeModel) getHibernateTemplate().load(CompositeModel.class, new Integer(nId));
}
public void storeComposite(CompositeModel composite) throws DataAccessException {
getHibernateTemplate().save(composite);
throw new DataAccessException("exception") {};
}
public void updateComposite(CompositeModel composite) throws DataAccessException {
getHibernateTemplate().update(composite);
}
public void deleteComposite(CompositeModel composite) throws DataAccessException {
getHibernateTemplate().delete(composite);
}
}
package example.framework;
import example.framework.model.CompositeModel;
import example.framework.persistent.CompositePM;
import net.sf.hibernate.HibernateException;
import org.springframework.context.support.ClassPathXmlAp plicationContext;
import java.util.ArrayList;
import java.util.List;
public class TestFramework {
private ClassPathXmlApplicationContext ac = null;
private CompositePM composite = null;
public void initFramework() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
composite = (CompositePM) ac.getBean("compositeTarget");
}
private void printComposite(CompositeModel composite) {
System.out.println(composite);
}
private void printComposite(List composites) {
for (int i=0; i<composites.size(); i++)
printComposite((CompositeModel) composites.get(i));
}
public List listAllComposite() {
return composite.listComposite();
}
public CompositeModel findComposite(int nId) {
return composite.findComposite(nId);
}
public void insertComposite(CompositeModel composite) throws HibernateException {
this.composite.storeComposite(composite);
}
public void performTest() throws HibernateException {
// select composite
List list = new ArrayList();
CompositeModel com = findComposite(1);
list.add(com);
printComposite(list);
CompositeModel c = null;
// insert successfully
c = new CompositeModel();
c.setId(10);
c.setParentId(2);
c.setName("new composite");
c.setDescription("Description");
composite.storeComposite(c);
}
public static void main(String[] agrs) throws HibernateException {
TestFramework tf = new TestFramework();
tf.initFramework();
tf.performTest();
}
}
I have encountered a problem when using Spring Transaction Management feature.
The following sources are based on the example petClinic sources.
But the TransactionProxyFactoryBean seem go wrong (maybe) when I intentionally throw a DataAccessException in storeComposite method.
The transaction still commit instead rollback.
Please help me. Thank you
--------- composite.hbm.xml -----------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hib...g-2.0.dtd">
<hibernate-mapping auto-import="true">
<class name="example.framework.model.CompositeModel" table="Composite">
<id name="id" type="int" unsaved-value="-1">
<generator class="assigned"/>
</id>
<set name="children" lazy="false" cascade="all">
<key column="parent_id"/>
<one-to-many class="example.framework.model.CompositeModel"/>
</set>
<property name="parentId" column="parent_id" type="java.lang.Integer"/>
<property name="name" type="java.lang.String"/>
<property name="description" type="java.lang.String"/>
</class>
</hibernate-mapping>
----------------jdbc.properties ---------------
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://localhost:9001
jdbc.username=sa
jdbc.password=
hibernate.dialect=net.sf.hibernate.dialect.HSQLDia lect
----------------- applicationContext.xml -----------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/s...beans.dtd">
<beans>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyP laceholderConfigurer">
<property name="location"><value>jdbc.properties</value></property>
</bean>
<!-- Local DataSource that works in any environment -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerD ataSource">
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
<property name="url"><value>${jdbc.url}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFact oryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<value>composite.hbm.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransac tionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="compositeTarget" class="example.framework.persistent.CompositePMImpl">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="proxy" class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean">
<property name="transactionManager"><ref local="transactionManager"/></property>
<property name="target"><ref local="compositeTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="store*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
------------- CompositeModel.java --------------------
package example.framework.model;
import java.util.Iterator;
import java.util.Set;
public class CompositeModel {
private int m_nId = 0;
private int m_nParentId = 0;
private String m_sName = null;
private String m_sDescription = null;
private CompositeModel m_parent = null;
private Set m_children = null;
public int getId() {
return m_nId;
}
public void setId(int m_nId) {
this.m_nId = m_nId;
}
public int getParentId() {
return m_nParentId;
}
public void setParentId(int m_nParentId) {
this.m_nParentId = m_nParentId;
}
public String getName() {
return m_sName;
}
public void setName(String m_sName) {
this.m_sName = m_sName;
}
public String getDescription() {
return m_sDescription;
}
public void setDescription(String m_sDescription) {
this.m_sDescription = m_sDescription;
}
public CompositeModel getParent() {
return m_parent;
}
public void setParent(CompositeModel m_parent) {
this.m_parent = m_parent;
}
public Set getChildren() {
return m_children;
}
public void setChildren(Set m_children) {
this.m_children = m_children;
}
public String toString() {
final StringBuffer buf = new StringBuffer();
buf.append("CompositeModel");
buf.append("\n\tm_nId=").append(m_nId);
buf.append("\n\tm_nParent=").append(m_nParentId);
buf.append("\n\tm_sName=").append(m_sName);
buf.append("\n\tm_sDescription=").append(m_sDescription);
buf.append("\n\tm_parent=").append(m_parent == null ? null : m_parent.toString());
Set children = getChildren();
if (children == null)
buf.append("\n\tHas no children");
else {
buf.append("\n\tNumber of children = " + children.size());
buf.append("\n\t{");
for (Iterator i = children.iterator(); i.hasNext();) {
CompositeModel com = (CompositeModel) i.next();
buf.append(com.toString());
}
buf.append("\n\t}");
}
buf.append("\n\t------------------");
return buf.toString();
}
}
---------CompositePM---------------
package example.framework.persistent;
import example.framework.model.CompositeModel;
import org.springframework.dao.DataAccessException;
import java.util.List;
public interface CompositePM {
public List listComposite();
public CompositeModel findComposite(int nId);
public void storeComposite(CompositeModel composite) throws DataAccessException;
public void updateComposite(CompositeModel composite) throws DataAccessException;
public void deleteComposite(CompositeModel composite) throws DataAccessException;
}
------CompositePMImpl---------------
package example.framework.persistent;
import example.framework.model.CompositeModel;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate.support.Hibernat eDaoSupport;
import java.util.List;
public class CompositePMImpl extends HibernateDaoSupport implements CompositePM {
public List listComposite() {
return getHibernateTemplate().find("from CompositeModel AS composite");
}
public CompositeModel findComposite(int nId) {
return (CompositeModel) getHibernateTemplate().load(CompositeModel.class, new Integer(nId));
}
public void storeComposite(CompositeModel composite) throws DataAccessException {
getHibernateTemplate().save(composite);
throw new DataAccessException("exception") {};
}
public void updateComposite(CompositeModel composite) throws DataAccessException {
getHibernateTemplate().update(composite);
}
public void deleteComposite(CompositeModel composite) throws DataAccessException {
getHibernateTemplate().delete(composite);
}
}
package example.framework;
import example.framework.model.CompositeModel;
import example.framework.persistent.CompositePM;
import net.sf.hibernate.HibernateException;
import org.springframework.context.support.ClassPathXmlAp plicationContext;
import java.util.ArrayList;
import java.util.List;
public class TestFramework {
private ClassPathXmlApplicationContext ac = null;
private CompositePM composite = null;
public void initFramework() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
composite = (CompositePM) ac.getBean("compositeTarget");
}
private void printComposite(CompositeModel composite) {
System.out.println(composite);
}
private void printComposite(List composites) {
for (int i=0; i<composites.size(); i++)
printComposite((CompositeModel) composites.get(i));
}
public List listAllComposite() {
return composite.listComposite();
}
public CompositeModel findComposite(int nId) {
return composite.findComposite(nId);
}
public void insertComposite(CompositeModel composite) throws HibernateException {
this.composite.storeComposite(composite);
}
public void performTest() throws HibernateException {
// select composite
List list = new ArrayList();
CompositeModel com = findComposite(1);
list.add(com);
printComposite(list);
CompositeModel c = null;
// insert successfully
c = new CompositeModel();
c.setId(10);
c.setParentId(2);
c.setName("new composite");
c.setDescription("Description");
composite.storeComposite(c);
}
public static void main(String[] agrs) throws HibernateException {
TestFramework tf = new TestFramework();
tf.initFramework();
tf.performTest();
}
}