Atomikos Forum

Atomikos+Hibernate+JMS: Hibernate rollback does not work.

Hi;
I integrated Atomikos, Hibernate and ActiveMQ using Spring but when I rollback a Hibernate action it is not work but jms rollback works.
==============================================================
this is my XML file:
[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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <!--  <bean id="localLogAdministrator" class="com.atomikos.icatch.admin.imp.LocalLogAdministrator" />-->
    <bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp" init-method="init" destroy-method="shutdownForce">
        <constructor-arg>
            <props>
                <prop key="com.atomikos.icatch.service">com.atomikos.icatch.standalone.UserTransactionServiceFactory</prop>
                <prop key="com.atomikos.icatch.tm_unique_name">fered</prop>
                <prop key="com.atomikos.icatch.log_base_name">fered</prop>
                <prop key="com.atomikos.icatch.log_base_dir">/tmp/</prop>
               
                <!-- DEBUGGING PROPERTIES -->
                <prop key="com.atomikos.icatch.output_dir">/tmp/</prop>
                <prop key="com.atomikos.icatch.console_file_name">atomikos.log</prop>
                <prop key="com.atomikos.icatch.console_log_level">DEBUG</prop>
                <prop key="com.atomikos.icatch.threaded_2pc">true</prop>
            </props>
        </constructor-arg>
    </bean>
    <!-- 
    Construct Atomikos UserTransactionManager,needed to configure Spring 
-->
    <bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close" depends-on="userTransactionService">

        <!-- IMPORTANT: disable startup because the userTransactionService above does this -->
        <property name="startupTransactionService" value="false" />

        <!--  when close is called,should we force transactions to terminate or not?  -->
        <property name="forceShutdown" value="true" />
    </bean>

    <!--Also use Atomikos UserTransactionImp,needed to configure Spring-->
    <bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" depends-on="userTransactionService">
        <property name="transactionTimeout" value="300" />
    </bean>

    <!--Configure the Spring framework to use JTA transactions from Atomikos-->
    <bean id="JtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" depends-on="userTransactionService">
        <property name="transactionManager" ref="AtomikosTransactionManager" />
        <property name="userTransaction" ref="AtomikosUserTransaction" />
    </bean>

    <!-- configure Hibernate to use the Atomikos JTA and datasource for transaction control -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <!-- add the mapped resources (hbm files) of your application -->
        <property name="mappingResources">
            <list>
                <value>Account.hbm.xml</value>
            </list>
        </property>

        <!-- make sure that hibernate uses the Atomikos datasource (JTA enabled)! -->
        <property name="dataSource">
            <ref bean="datasource" />
        </property>

        <!-- configure hibernate to use Atomikos TransactionsEssentials -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.transaction.factory_class">
                    com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory
                    <!--
                    com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory
                     org.hibernate.transaction.JTATransactionFactory
                     org.hibernate.transaction.JDBCTransactionFactory
                     -->
                </prop>


                <prop key="hibernate.transaction.manager_lookup_class">
                    com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
                        </prop>

                <!-- for hibernate 2, use the following: <prop key="hibernate.transaction.manager_lookup_class">
                    com.atomikos.icatch.jta.hibernate.TransactionManagerLookup </prop> -->
                <!-- add any other hibernate properties you need -->

                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <!-- Enable Hibernate's automatic session context management -->
                <prop key="hibernate.current_session_context_class">jta</prop>
                <!-- Disable the second-level cache -->
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
                <!-- Echo all executed SQL to stdout -->
                <prop key="hibernate.show_sql">true</prop>
                <!-- Drop and re-create the database schema on startup -->
                <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
            </props>
        </property>

    </bean>

    <!-- configure the Spring hibernate template with the session factory from above -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>
    <!-- a class that implements javax.jms.MessageListener -->
    <bean id="MessageListener" class="TextOutputMessageListener" />

    <!-- Configure the JMS template used to send messages -->
    <bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="ConnectionFactory" />
        <property name="sessionTransacted" value="true" />
    </bean>
    <!-- create real business object, this is your own implementation -->
    <bean id="RealAccountFacade" class="AccountFacade">
        <property name="jmsTemplate" ref="JmsTemplate" />
        <property name="queue" ref="Queue" />
    </bean>

    <!-- wrap real business object with a spring-generated JTA proxy this is the only object that need to be obtained from the ApplicationContext -->
    <bean id="AccountFacade" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="JtaTransactionManager" />
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED, -Exception</prop>
            </props>
        </property>
        <property name="target" ref="RealAccountFacade" />
    </bean>

    <bean id="RealAccountManager" class="AccountManager">
        <property name="hibernateTemplate" ref="hibernateTemplate" />
    </bean>

    <bean id="AccountManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="JtaTransactionManager" />
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED, -Exception</prop>
            </props>
        </property>
        <property name="target" ref="RealAccountManager" />
    </bean>
    <!-- configure an Atomikos JTA-aware datasource -->
    <bean id="datasource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
        <!-- set an arbitrary but unique name for the datasource -->
        <property name="uniqueResourceName">
            <value>XADBMS</value>
        </property>
        <!-- set the underlying driver class to use, in this example case we use
            Oracle -->
        <property name="xaDataSourceClassName">
            <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>
        </property>
        <!-- set the driver-specific XADataSource properties (check your driver
            docs for more info) -->
        <property name="xaProperties">
            <props>
                <prop key="user">fered</prop>
                <prop key="password">123456</prop>
                <prop key="URL">jdbc:mysql://localhost:3306/AtomikosHibernate</prop>
            </props>
        </property>
        <!-- how many connections in the pool? -->
        <property name="poolSize" value="1" />
    </bean>



    <!-- Allows us to set properties used as ant-like variables ${...} -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="properties">
            <props>
                <prop key="poolSize">1</prop>
                <prop key="outboundQueueName">outQ</prop>
                <prop key="AckQueueName">inQ</prop>
            </props>
        </property>
    </bean>

    <bean id="xaFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616" />
    </bean>

    <!-- Configure the JMS connector; call init to register for recovery! -->
    <bean id="RealConnectionFactory" class="com.atomikos.jms.QueueConnectionFactoryBean" init-method="init">
        <property name="resourceName" value="amq1" />
        <property name="xaQueueConnectionFactory" ref="xaFactory" />
    </bean>

    <bean id="ConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
        <property name="targetConnectionFactory" ref="RealConnectionFactory" />
    </bean>

    <bean id="Queue" class="org.apache.activemq.command.ActiveMQQueue">
        <property name="physicalName" value="${outboundQueueName}" />
    </bean>
</beans>
[/code]
=============================================================
and this is main:
[code]
    public static void main(String[] args) throws JMSException, InterruptedException, NotSupportedException, SystemException, IllegalStateException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {

        AccountFacade accountFacade = (AccountFacade) ContextManager.getBean("AccountFacade");

        AccountManager accountManager = (AccountManager) ContextManager.getBean("AccountManager");
        while (true) {
            JtaTransactionManager jtaTransactionManager = (JtaTransactionManager) ContextManager.getBean("JtaTransactionManager");


            jtaTransactionManager.getUserTransaction().begin();

            Account account = accountFacade.getAcount();
            
            System.out.println(account.getAccountNo());
        
            accountManager.creatAndStoreAccount(account);
            

                System.out.println("rollback");
                jtaTransactionManager.getUserTransaction().rollback();
            Thread.sleep(1000);
        }
    }
[/code]
============================================================
other classes:
[code]
public class AccountFacade {
   
    private JmsTemplate jmsTemplate;
    private Queue queue;
   
    public AccountFacade() {
    }

    public void setJmsTemplate(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }
   
    public void setQueue(Queue queue) {
        this.queue = queue;
    }
    public Account getAcount() throws JMSException
    {
        Message message = jmsTemplate.receive(queue);
        if (message instanceof ObjectMessage) {
            Account account = (Account)( (ObjectMessage) message).getObject();
            return account;
        }
    return null;
    }
}

public class AccountManager {

    HibernateTemplate hibernateTemplate;

    public AccountManager() {
        super();
    }

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
        this.hibernateTemplate.setFlushMode(HibernateTemplate.FLUSH_AUTO);
    }

    public void creatAndStoreAccount(final Account account) {
        hibernateTemplate.save(account);
    }
}

[/code]

after rollback, jms queue, requeue the received message but the saved object does not remove from database and hibernate does not rollback save.

what's the problem?

thanks.
Fered Send private email
Tuesday, August 03, 2010
 
 
What versions of each are you using?
Guy Pardon Send private email
Tuesday, August 03, 2010
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics