Oct 6th, 2012, 04:22 PM
When using Spring JPA is it strictly required to use Spring TX demarcation
In a Web app of mine that uses Spring's
a) org.springframework.transaction.jta.JtaTransaction Manager as Spring TX Manager
over an external JTA implementation and
b) org.springframework.orm.jpa.LocalContainerEntityMa nagerFactoryBean as EMF
I a noticed the following behavior:
When I try to control transaction boundaries via a servlet filter that uses the UserTransaction object, Spring's EM seems to be not registered with the TX. I.e. persistent object get detached right away.
When I use @Transactional however, everything works as expected. When digging for a root cause of this I noticed that TransactionSynchronizationManager is the class managing resource binding to the tx and require Spring proprietary initialization.
Is it true then that the observed behavior can be expected? And is there a way to bridge these two TX implementations, so that it is possible to control transaction demarcation outside of spring and still have everything work?
Oct 8th, 2012, 12:51 AM
By simply annotating your methods with @Transactional and configuring your LCEMF correctly. Spring will then register with the ongoing transaction.... So start with the @Transactional and make sure you have everything configured correctly.
Oct 8th, 2012, 03:20 AM
Right. And it works, if I do that. The actual question was, if I can use pure JTA transaction demarcation instead.
Or, put differently, is there a way to set up the Spring transaction manager (PlatformTransactionManager et al) to work with a transaction demarcation that is simply based on the JTA UserTransaction Object, say in a given servlet filter.
In the specific scenario I am using the Vaadin UI framework. In order to demarcate a transaction that spans the whole request there is no single method to annotate with @Transactional (unless of course I add a filter). But there is HttpServletRequestListener methods (start and end of request) that can be used. The most standard way of demarcating the transaction would be to use the UserTransaction object. I would prefer that over using Spring's programmatic transaction demarcation.
Oct 8th, 2012, 03:26 AM
I suggest you do some reading about how JTA works...
Starting a JTA transaction doesn't automatically register all possible transactional resources... Transactional resources will have to register themselves with the ongoing context as soon as they need a transaction you need to either manually manage it or use another means (i.e. annotations) to register/attach to the transaction.
So you need both... Also be aware that the way you are doing now has some issues, if rendering of your web page fails so does the transaction not sure if you want your transaction be dependend on the web layer. I wouldn't ...
Oct 8th, 2012, 03:43 AM
hmm... I think I am rather well aware about how JTA works.
I was not asking for automatic registration of transactional resources. I was asking for a less intrusive way of having Spring resources join the current transaction.
See, if I use Hibernate JPA without Spring but as part of a JTA transaction. Then Hibernate registers a transaction synchronization so it can flush its EM before the transaction commits and there is no need otherwise to tell Hibernate about begin and end of the tx.
Spring uses similar mechanisms to bind its EM to the current transaction. However it seems to have a layer in between that abstracts from the fact whether there is actually a JTA transaction manager present or whether it is Spring pure play.
Now, when there is a JTA transaction manager present, Spring still wants its own synchronization mechanism initialized (which seems to be part of what @Transactional does) rather than just registering with the already present JTA TM.
My question was an attempt to find out if there is a simple (preferrably declarative) way to tell Spring's TM to rely on the JTA TM directly rather than requiring Spring's own demarcation.
Oct 8th, 2012, 04:01 AM
If you use hibernate without spring you tell hibernate to start a transaction (or join an existing one) this doesn't change when using spring... But instead of starting the transaction your self you let this be done by spring and to do this you need @Transactional...
If it works with plain hibernate then use plain hibernate and ditch spring (why use a framework if you can do without ?!), however I suspect when using plain hibernate JPA you are using a container managed EMF with or without EJB3 and then there is some container magic kicking in.
Spring needs to be able to work in either environment and as such requires transaction demarcation it needs this to do resource managemet and to be able to inject the EntityManager.