Hello,
We have the following problem.
the pipeline is simple:
gateway->transformer->splitter->service-activator
we hit the gateway and pass our Roo generated objects.
We then pass the Roo object as the payload.
Transformer is able to access lazy loaded collections on the payload, find some other roo managed objects update them, persist/merge them.
Everything is fine.
However, this is not the case with SA.
It throws LazyLoading exception after the first Roo finder, we execute in SA.
When i turn on the spring orm jpa logging, things became more clear.
This is the trace when message reaches SA:
Interesting thing is that it looks like previuosly executed transformer had different transaction and entity manager!?Code:11:05:56,750 DEBUG MyServiceActivator.execute(23) | started service activator 11:05:56,752 DEBUG SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(231) | Creating new EntityManager for shared EntityManager invocation 11:05:56,759 DEBUG EntityManagerFactoryUtils.closeEntityManager(328) | Closing JPA EntityManager 11:05:56,763 ERROR LazyInitializationException.<init>(42) | failed to lazily initialize a collection of role: com.acme.core.model.config.MyConfig.tasks, no session or session was closed org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.acme.core.model.config.MyConfig.tasks, no session or session was closed
Why? I have direct channel, between all the components.Code:11:05:55,998 DEBUG JpaTransactionManager.processCommit(752) | Initiating transaction commit 11:05:55,998 DEBUG JpaTransactionManager.doCommit(462) | Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@1d4ab266] 11:05:56,000 DEBUG JpaTransactionManager.doCleanupAfterCompletion(548) | Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@1d4ab266] after transaction 11:05:56,000 DEBUG EntityManagerFactoryUtils.closeEntityManager(328) | Closing JPA EntityManager
I execute transformer and splitter in chain, and SA outside the chain.
Adding SA in chain didn't help.
My understanding after reading Transaction boundaries chapter in spring ref guide, is that I should have the same transaction context in piepline if I have direct channels between message handlers, which I do.
How I eventually solved the issue:
I put @Transactional annotation on my SA and surprisingly everything works, no LazyLoading problem. Looks like TransactionManager is also different (now it is JPA)...
Code:09:26:19,870 JpaTransactionManager.getTransaction(365) | Creating new transaction with name [com.acme.MyServiceActivator.execute]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 09:26:19,871 DEBUG JpaTransactionManager.doBegin(323) | Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@52f3424a] for JPA transaction
I think I don't understand things here deep enough.
Why is this happening?
Thanks a lot for any hint or explanation.
Milan


Reply With Quote