I'm still fighting against Spring config or Camel because Rollback does not
occur. I have been able to configure Hibernate to use the same
TransactionManager as the one used by JMS
Here is the different part of the config. I don't know where the issue could
be !
1) ActiveMQ
...
<bean id="activemqConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<bean id="pooledConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactoryBean">
<property name="maxConnections" value="8" />
<property name="maximumActive" value="500" />
<property name="transactionManager" ref="transactionManager" />
<property name="connectionFactory" ref="activemqConnectionFactory"
/>
<property name="resourceName" value="activemq.default" />
</bean>
<bean id="resourceManager"
class="org.apache.activemq.pool.ActiveMQResourceManager"
init-method="recoverResource">
<property name="transactionManager" ref="transactionManager" />
<property name="connectionFactory" ref="activemqConnectionFactory"
/>
<property name="resourceName" value="activemq.default" />
</bean>
<osgi:reference id="transactionManager"
interface="javax.transaction.TransactionManager" /> // This OSGI service is
published by Geronimo Transaction bundle
<osgi:service ref="pooledConnectionFactory">
<osgi:interfaces>
<value>javax.jms.ConnectionFactory</value>
</osgi:interfaces>
<osgi:service-properties>
<entry key="name" value="default"/>
</osgi:service-properties>
</osgi:service>
2) Camel ActiveMQComponent
<bean id="active-mq"
class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="transacted" value="true"/>
<property name="connectionFactory">
<osgi:reference interface="javax.jms.ConnectionFactory"/> //
OSGI service is published by ActiveMQ service
</property>
<property name="transactionManager">
<osgi:reference
interface="org.springframework.transaction.PlatformTransactionManager"/>
</property>
</bean>
2) Hibernate - DAO
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingLocations">
<list>
<value>classpath*:META-INF/com/xpectis/x3s/platform/model/*.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop
key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop
key="hibernate.cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop
key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
<prop
key="hibernate.transaction.factory_class">org.springframework.orm.hibernate3.SpringTransactionFactory</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
Remark : To avoid the JNDI lookup issue, we use springTransactionFactory as
the TransactionFactory for Hibernate (
http://forum.springsource.org/showthread.php?p=215720)
3) Service layer
Here is the definition of the service used from Camel route :
<bean id="notificationServiceTarget"
class="com.xpectis.x3s.platform.service.impl.NotificationServiceImpl">
<property name="notificationDAO">
<osgi:reference
interface="com.xpectis.x3s.platform.dao.NotificationDAO"/>
</property>
</bean>
<!-- Abstract service using the Geronimo Transaction Manager -->
<bean id="abstractService" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<osgi:reference
interface="org.springframework.transaction.PlatformTransactionManager"/>
</property>
</bean>
<bean id="notificationService"
parent="abstractService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target">
<ref bean="notificationServiceTarget" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
4) Route
<bean id="myPolicy" class="org.apache.camel.processor.RedeliveryPolicy">
<property name="maximumRedeliveries" value="1"/>
</bean>
<bean id="txErrorHandler"
class="org.apache.camel.spring.spi.TransactionErrorHandlerBuilder">
<property name="springTransactionPolicy"
ref="PROPAGATION_REQUIRED"/>
<property name="redeliveryPolicy" ref="myPolicy"/>
</bean>
<bean id="PROPAGATION_REQUIRED"
class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager">
<osgi:reference
interface="org.springframework.transaction.PlatformTransactionManager"/>
</property>
</bean>
<camel:route errorHandlerRef="txErrorHandler">
<camel:from ref="queueQuickFixInEndpoint" />
<camel:convertBodyTo type="quickfix.Message" />
<camel:transacted ref="PROPAGATION_REQUIRED"/>
<camel:bean ref="serviceHelper" method="createNotification" />
<camel:bean ref="serviceHelper" method="generateError" />
<camel:to ref="directNotificationEndpoint" />
</camel:route>
Any ideas are welcome
Regards,
Charles Moulliard
Senior Enterprise Architect
Apache Camel Committer
*****************************
blog :
http://cmoulliard.blogspot.comOn Thu, Jul 2, 2009 at 5:02 PM, Charles Moulliard <
cmoulliard@...>wrote:
> OK. I will try to create my own Hibernate JTATransaction manager as the
> existing try to perform a JNDI lookup to find the transaction manager on
> OSGI platform (inheritage from J2EE world)
>
>
>
http://mail-archives.apache.org/mod_mbox/servicemix-dev/200904.mbox/%3Cb23ecedc0904020615y55df4d0fhb303a2ea22df7a53@...%3E>
>
> Charles Moulliard
> Senior Enterprise Architect
> Apache Camel Committer
>
> *****************************
> blog :
http://cmoulliard.blogspot.com>
>
> On Thu, Jul 2, 2009 at 4:56 PM, Claus Ibsen <
claus.ibsen@...> wrote:
>
>> On Thu, Jul 2, 2009 at 4:53 PM, Charles Moulliard<
cmoulliard@...>
>> wrote:
>> > queueQuickFixInEndpoint is a JMS queue.
>> >
>> > I will add the ref to the transacted and retest
>> >
>> > Question : I suppose that rollback will not occur if by example JMS and
>> DB
>> > (=Hibernate) does not use the same TransactionManager and don't use this
>> > spring class together :
>> > org.springframework.transaction.PlatformTransactionManager
>> Yes they must be configured to use the same TX manager.
>>
>>
>> >
>> > Regards,
>> >
>> > Charles Moulliard
>> > Senior Enterprise Architect
>> > Apache Camel Committer
>> >
>> > *****************************
>> > blog :
http://cmoulliard.blogspot.com>> >
>> >
>> > On Thu, Jul 2, 2009 at 4:46 PM, Claus Ibsen <
claus.ibsen@...>
>> wrote:
>> >
>> >> Transacted also have a ref attribute
>> >>
>> >> <transacted ref="required"/>
>> >>
>> >> Is queueQuickFixInEndpoint a JMS queue?
>> >> You need to use a TX manager that can do both JMS and DB.
>> >>
>> >>
>> >>
>> >> On Thu, Jul 2, 2009 at 4:31 PM, Charles Moulliard<
cmoulliard@...
>> >
>> >> wrote:
>> >> > I have been able to solve my problem by adding the following bean
>> >> definition
>> >> > :
>> >> >
>> >> > <bean id="required"
>> >> > class="org.apache.camel.spring.spi.SpringTransactionPolicy">
>> >> > <property name="transactionManager">
>> >> > <osgi:reference
>> >> >
>> interface="org.springframework.transaction.PlatformTransactionManager"/>
>> >> > </property>
>> >> > </bean>
>> >> >
>> >> > and in the route
>> >> >
>> >> > <camel:route>
>> >> > <camel:from ref="queueQuickFixInEndpoint" />
>> >> > <camel:convertBodyTo type="quickfix.Message" />
>> >> > <camel:transacted/>
>> >> > <camel:policy ref="required" />
>> >> > <camel:bean ref="serviceHelper"
>> method="createNotification" />
>> >> > <camel:bean ref="serviceHelper" method="generateError" />
>> >> > <camel:to ref="directNotificationEndpoint" />
>> >> > </camel:route>
>> >> >
>> >> > Unfortunately, the rollback does not occur in the DB and 6 records
>> have
>> >> been
>> >> > created by the method createNotification when error has been raised
>> by
>> >> the
>> >> > method generateError.
>> >> >
>> >> > What is missing ?
>> >> >
>> >> > Charles Moulliard
>> >> > Senior Enterprise Architect
>> >> > Apache Camel Committer
>> >> >
>> >> > *****************************
>> >> > blog :
http://cmoulliard.blogspot.com>> >> >
>> >> >
>> >> > On Thu, Jul 2, 2009 at 4:19 PM, Charles Moulliard <
>>
cmoulliard@...
>> >> >wrote:
>> >> >
>> >> >> When I compare the example : JMSTransactionalClientRollbackTest.xml
>> >> >>
>> >> >> <!-- START SNIPPET: e1 -->
>> >> >> <!-- setup JMS connection factory -->
>> >> >> <bean id="jmsConnectionFactory"
>> >> >> class="org.apache.activemq.ActiveMQConnectionFactory">
>> >> >> <property name="brokerURL"
>> >> >>
>> value="vm://localhost?broker.persistent=false&broker.useJmx=false"/>
>> >> >> </bean>
>> >> >>
>> >> >> <!-- setup spring jms TX manager -->
>> >> >> <bean id="jmsTransactionManager"
>> >> >> class="org.springframework.jms.connection.JmsTransactionManager">
>> >> >> <property name="connectionFactory"
>> ref="jmsConnectionFactory"/>
>> >> >> </bean>
>> >> >>
>> >> >> <!-- define our activemq component -->
>> >> >> <bean id="activemq"
>> >> >> class="org.apache.activemq.camel.component.ActiveMQComponent">
>> >> >> <property name="connectionFactory"
>> ref="jmsConnectionFactory"/>
>> >> >> <!-- define the jms consumer/producer as transacted -->
>> >> >> <property name="transacted" value="true"/>
>> >> >> <!-- setup the transaction manager to use -->
>> >> >> <!-- if not provided then Camel will automatic use a
>> >> >> JmsTransactionManager, however if you
>> >> >> for instance use a JTA transaction manager then you
>> must
>> >> >> configure it -->
>> >> >> <property name="transactionManager"
>> >> ref="jmsTransactionManager"/>
>> >> >> </bean>
>> >> >> <!-- END SNIPPET: e1 -->
>> >> >>
>> >> >> <!-- START SNIPPET: e2 -->
>> >> >> <camelContext xmlns="
http://camel.apache.org/schema/spring">
>> >> >> <route>
>> >> >> <!-- 1: from the jms queue -->
>> >> >> <from uri="activemq:queue:okay"/>
>> >> >> <!-- 2: mark this route as transacted -->
>> >> >> <transacted/>
>> >> >> <!-- 3: call our business logic that is myProcessor -->
>> >> >> <process ref="myProcessor"/>
>> >> >> <!-- 4: if success then send it to the mock -->
>> >> >> <to uri="mock:result"/>
>> >> >> </route>
>> >> >> </camelContext>
>> >> >>
>> >> >> with mine.
>> >> >>
>> >> >> What is different concerns the TransactionManager used.
>> >> >>
>> >> >> In the example, this is the Spring one:
>> >> >>
>> >> >> <!-- setup spring jms TX manager -->
>> >> >> <bean id="jmsTransactionManager"
>> >> >> class="org.springframework.jms.connection.JmsTransactionManager">
>> >> >> <property name="connectionFactory"
>> ref="jmsConnectionFactory"/>
>> >> >> </bean>
>> >> >>
>> >> >> and in my case, ActiveMQ is configured to use Geronimo Transaction
>> >> Manager
>> >> >> bundle (which in fact uses spring Transaction manager :
>> >> >> org.springframework.transaction.jta.JtaTransactionManager;)
>> >> >>
>> >> >> I suppose that in the example, the policy is defined by default by
>> >> spring
>> >> >> when instantiating the class :
>> >> >> org.springframework.jms.connection.JmsTransactionManager
>> >> >>
>> >> >> Is it possible to do the same using a JtaTransaction manager ?
>> >> >>
>> >> >> Regards,
>> >> >>
>> >> >> Charles Moulliard
>> >> >> Senior Enterprise Architect
>> >> >> Apache Camel Committer
>> >> >>
>> >> >> *****************************
>> >> >> blog :
http://cmoulliard.blogspot.com>> >> >>
>> >> >>
>> >> >> On Thu, Jul 2, 2009 at 3:57 PM, Claus Ibsen <
claus.ibsen@...>
>> >> wrote:
>> >> >>
>> >> >>> Hi
>> >> >>>
>> >> >>> Yeah you need to add all the spring transaction stuff.
>> >> >>>
>> >> >>>
>> >> >>> On Thu, Jul 2, 2009 at 3:47 PM, Charles Moulliard<
>>
cmoulliard@...
>> >> >
>> >> >>> wrote:
>> >> >>> > Camel generates the following error with my route :
>> >> >>> >
>> >> >>> > Route
>> >> >>> >
>> >> >>> > <camel:route>
>> >> >>> > <camel:from ref="queueQuickFixInEndpoint" />
>> >> >>> > <camel:convertBodyTo type="quickfix.Message" />
>> >> >>> > <camel:transacted/>
>> >> >>> > <camel:bean ref="serviceHelper"
>> >> method="createNotification"
>> >> >>> />
>> >> >>> > <camel:bean ref="serviceHelper" method="generateError"
>> />
>> >> >>> > <camel:to ref="directNotificationEndpoint" />
>> >> >>> > </camel:route>
>> >> >>> >
>> >> >>> > It seems that policy must be defined but in the example here it
>> is
>> >> not
>> >> >>> > mentioned :
http://camel.apache.org/transactional-client.html>> >> >>> >
>> >> >>> > Error :
>> >> >>> >
>> >> >>> > 15:43:07,838 | ERROR | xtenderThread-30 | ContextLoaderListener
>> >> >>> |
>> >> >>> > BundleApplicationContextListener 50 | Application context
>> refresh
>> >> >>> failed
>> >> >>> > (OsgiBundleXmlApplicationContext(bundle=com.xpectis.x3s.x3s-core,
>> >> >>> > config=osgibundle:/META-INF/spring/*.xml))
>> >> >>> > org.apache.camel.RuntimeCamelException:
>> >> >>> java.lang.IllegalArgumentException:
>> >> >>> > policy must be specified on: Transacted[ref: null]
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:986)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:121)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:465)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.context.event.SimpleApplicationEventMulticaster$1.run(SimpleApplicationEventMulticaster.java:78)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:76)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:274)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:736)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.osgi.context.support.AbstractOsgiBundleApplicationContext.finishRefresh(AbstractOsgiBundleApplicationContext.java:235)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:358)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:136)
>> >> >>> > at java.lang.Thread.run(Thread.java:619)
>> >> >>> > Caused by: java.lang.IllegalArgumentException: policy must be
>> >> specified
>> >> >>> on:
>> >> >>> > Transacted[ref: null]
>> >> >>> > at
>> >> org.apache.camel.util.ObjectHelper.notNull(ObjectHelper.java:258)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.model.TransactedDefinition.createProcessor(TransactedDefinition.java:129)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.model.ProcessorDefinition.makeProcessor(ProcessorDefinition.java:226)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.model.ProcessorDefinition.addRoutes(ProcessorDefinition.java:111)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:294)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:120)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:552)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:969)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:946)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.spring.SpringCamelContext.maybeDoStart(SpringCamelContext.java:165)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.spring.SpringCamelContext.doStart(SpringCamelContext.java:160)
>> >> >>> > at
>> >> org.apache.camel.impl.ServiceSupport.start(ServiceSupport.java:52)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:863)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.spring.SpringCamelContext.maybeStart(SpringCamelContext.java:99)
>> >> >>> > at
>> >> >>> >
>> >> >>>
>> >>
>> org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:119)
>> >> >>> > Charles Moulliard
>> >> >>> > Senior Enterprise Architect
>> >> >>> > Apache Camel Committer
>> >> >>> >
>> >> >>> > *****************************
>> >> >>> > blog :
http://cmoulliard.blogspot.com>> >> >>> >
>> >> >>>
>> >> >>>
>> >> >>>
>> >> >>> --
>> >> >>> Claus Ibsen
>> >> >>> Apache Camel Committer
>> >> >>>
>> >> >>> Open Source Integration:
http://fusesource.com>> >> >>> Blog:
http://davsclaus.blogspot.com/>> >> >>> Twitter:
http://twitter.com/davsclaus>> >> >>>
>> >> >>
>> >> >>
>> >> >
>> >>
>> >>
>> >>
>> >> --
>> >> Claus Ibsen
>> >> Apache Camel Committer
>> >>
>> >> Open Source Integration:
http://fusesource.com>> >> Blog:
http://davsclaus.blogspot.com/>> >> Twitter:
http://twitter.com/davsclaus>> >>
>> >
>>
>>
>>
>> --
>> Claus Ibsen
>> Apache Camel Committer
>>
>> Open Source Integration:
http://fusesource.com>> Blog:
http://davsclaus.blogspot.com/>> Twitter:
http://twitter.com/davsclaus>>
>
>