Announcement Announcement Module
Collapse
No announcement yet.
Cannot rollback tx when using TransactionProxyFactoryBean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cannot rollback tx when using TransactionProxyFactoryBean

    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

    Code:
    --------- composite.hbm.xml -----------
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD//EN"
            "http&#58;//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&#58;hsqldb&#58;hsql&#58;//localhost&#58;9001
    jdbc.username=sa
    jdbc.password=
    
    hibernate.dialect=net.sf.hibernate.dialect.HSQLDialect
    
    
    
    ----------------- applicationContext.xml -----------
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/s...beans.dtd">
    <beans>
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location"><value>jdbc.properties</value></property>
        </bean>
    
        <!-- Local DataSource that works in any environment -->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName"><value>$&#123;jdbc.driverClassName&#125;</value></property>
            <property name="url"><value>$&#123;jdbc.url&#125;</value></property>
            <property name="username"><value>$&#123;jdbc.username&#125;</value></property>
            <property name="password"><value>$&#123;jdbc.password&#125;</value></property>
        </bean>
    
        <!-- Hibernate SessionFactory -->
        <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
            <property name="dataSource"><ref local="dataSource"/></property>
            <property name="mappingResources">
                <value>composite.hbm.xml</value>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">$&#123;hibernate.dialect&#125;</prop>
                    <prop key="hibernate.show_sql">true</prop>
                </props>
            </property>
        </bean>
    
        <!-- Transaction manager for a single Hibernate SessionFactory &#40;alternative to JTA&#41; -->
        <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
            <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.TransactionProxyFactoryBean">
            <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 &#123;
        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&#40;&#41; &#123;
            return m_nId;
        &#125;
    
        public void setId&#40;int m_nId&#41; &#123;
            this.m_nId = m_nId;
        &#125;
    
        public int getParentId&#40;&#41; &#123;
            return m_nParentId;
        &#125;
    
        public void setParentId&#40;int m_nParentId&#41; &#123;
            this.m_nParentId = m_nParentId;
        &#125;
    
        public String getName&#40;&#41; &#123;
            return m_sName;
        &#125;
    
        public void setName&#40;String m_sName&#41; &#123;
            this.m_sName = m_sName;
        &#125;
    
        public String getDescription&#40;&#41; &#123;
            return m_sDescription;
        &#125;
    
        public void setDescription&#40;String m_sDescription&#41; &#123;
            this.m_sDescription = m_sDescription;
        &#125;
    
        public CompositeModel getParent&#40;&#41; &#123;
            return m_parent;
        &#125;
    
        public void setParent&#40;CompositeModel m_parent&#41; &#123;
            this.m_parent = m_parent;
        &#125;
    
        public Set getChildren&#40;&#41; &#123;
            return m_children;
        &#125;
    
        public void setChildren&#40;Set m_children&#41; &#123;
            this.m_children = m_children;
        &#125;
    
        public String toString&#40;&#41; &#123;
            final StringBuffer buf = new StringBuffer&#40;&#41;;
            buf.append&#40;"CompositeModel"&#41;;
            buf.append&#40;"\n\tm_nId="&#41;.append&#40;m_nId&#41;;
            buf.append&#40;"\n\tm_nParent="&#41;.append&#40;m_nParentId&#41;;
            buf.append&#40;"\n\tm_sName="&#41;.append&#40;m_sName&#41;;
            buf.append&#40;"\n\tm_sDescription="&#41;.append&#40;m_sDescription&#41;;
            buf.append&#40;"\n\tm_parent="&#41;.append&#40;m_parent == null ? null &#58; m_parent.toString&#40;&#41;&#41;;
    
            Set children = getChildren&#40;&#41;;
            if &#40;children == null&#41;
                buf.append&#40;"\n\tHas no children"&#41;;
            else &#123;
                buf.append&#40;"\n\tNumber of children = " + children.size&#40;&#41;&#41;;
                buf.append&#40;"\n\t&#123;"&#41;;
                for &#40;Iterator i = children.iterator&#40;&#41;; i.hasNext&#40;&#41;;&#41; &#123;
                    CompositeModel com = &#40;CompositeModel&#41; i.next&#40;&#41;;
                    buf.append&#40;com.toString&#40;&#41;&#41;;
                &#125;
                buf.append&#40;"\n\t&#125;"&#41;;
            &#125;
    
            buf.append&#40;"\n\t------------------"&#41;;
            return buf.toString&#40;&#41;;
        &#125;
    &#125;
    
    
    
    ---------CompositePM---------------
    package example.framework.persistent;
    
    import example.framework.model.CompositeModel;
    import org.springframework.dao.DataAccessException;
    
    import java.util.List;
    
    public interface CompositePM &#123;
        public List listComposite&#40;&#41;;
        public CompositeModel findComposite&#40;int nId&#41;;
        public void storeComposite&#40;CompositeModel composite&#41; throws DataAccessException;
        public void updateComposite&#40;CompositeModel composite&#41; throws DataAccessException;
        public void deleteComposite&#40;CompositeModel composite&#41; throws DataAccessException;
    &#125;
    
    
    ------CompositePMImpl---------------
    package example.framework.persistent;
    
    import example.framework.model.CompositeModel;
    import org.springframework.dao.DataAccessException;
    import org.springframework.orm.hibernate.support.HibernateDaoSupport;
    
    import java.util.List;
    
    public class CompositePMImpl extends HibernateDaoSupport implements CompositePM &#123;
        public List listComposite&#40;&#41; &#123;
            return getHibernateTemplate&#40;&#41;.find&#40;"from CompositeModel AS composite"&#41;;
        &#125;
    
        public CompositeModel findComposite&#40;int nId&#41; &#123;
            return &#40;CompositeModel&#41; getHibernateTemplate&#40;&#41;.load&#40;CompositeModel.class, new Integer&#40;nId&#41;&#41;;
        &#125;
    
        public void storeComposite&#40;CompositeModel composite&#41; throws DataAccessException &#123;
            getHibernateTemplate&#40;&#41;.save&#40;composite&#41;;
            throw new DataAccessException&#40;"exception"&#41; &#123;&#125;;
        &#125;
    
        public void updateComposite&#40;CompositeModel composite&#41; throws DataAccessException &#123;
            getHibernateTemplate&#40;&#41;.update&#40;composite&#41;;
        &#125;
    
        public void deleteComposite&#40;CompositeModel composite&#41; throws DataAccessException &#123;
            getHibernateTemplate&#40;&#41;.delete&#40;composite&#41;;
        &#125;
    &#125;
    
    
    
    package example.framework;
    
    import example.framework.model.CompositeModel;
    import example.framework.persistent.CompositePM;
    import net.sf.hibernate.HibernateException;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class TestFramework &#123;
    
        private ClassPathXmlApplicationContext ac = null;
        private CompositePM composite = null;
    
        public void initFramework&#40;&#41; &#123;
            ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext&#40;"applicationContext.xml"&#41;;
            composite = &#40;CompositePM&#41; ac.getBean&#40;"compositeTarget"&#41;;
        &#125;
    
        private void printComposite&#40;CompositeModel composite&#41; &#123;
            System.out.println&#40;composite&#41;;
        &#125;
    
        private void printComposite&#40;List composites&#41; &#123;
            for &#40;int i=0; i<composites.size&#40;&#41;; i++&#41;
                printComposite&#40;&#40;CompositeModel&#41; composites.get&#40;i&#41;&#41;;
        &#125;
    
        public List listAllComposite&#40;&#41; &#123;
            return composite.listComposite&#40;&#41;;
        &#125;
    
        public CompositeModel findComposite&#40;int nId&#41; &#123;
            return composite.findComposite&#40;nId&#41;;
        &#125;
    
        public void insertComposite&#40;CompositeModel composite&#41; throws HibernateException &#123;
            this.composite.storeComposite&#40;composite&#41;;
        &#125;
    
        public void performTest&#40;&#41; throws HibernateException &#123;
            // select composite
            List list = new ArrayList&#40;&#41;;
            CompositeModel com = findComposite&#40;1&#41;;
            list.add&#40;com&#41;;
            printComposite&#40;list&#41;;
    
            CompositeModel c = null;
            // insert successfully
            c = new CompositeModel&#40;&#41;;
            c.setId&#40;10&#41;;
            c.setParentId&#40;2&#41;;
            c.setName&#40;"new composite"&#41;;
            c.setDescription&#40;"Description"&#41;;
            composite.storeComposite&#40;c&#41;;
        &#125;
    
        public static void main&#40;String&#91;&#93; agrs&#41; throws HibernateException &#123;
            TestFramework tf = new TestFramework&#40;&#41;;
    
            tf.initFramework&#40;&#41;;
            tf.performTest&#40;&#41;;
        &#125;
    &#125;

  • #2
    It seems you're retrieving the target instead of the proxy here:

    Code:
    composite = &#40;CompositePM&#41; ac.getBean&#40;"compositeTarget"&#41;;
    Change this to

    Code:
    composite = &#40;CompositePM&#41; ac.getBean&#40;"proxy"&#41;;
    and you should be just fine...

    regards,
    Alef

    Comment

    Working...
    X