Spring JPA: context for continuous application implementation with @Transactional and @PersistenceContext

I'm currently trying to use an application-driven context context by manually creating an entity manager and saving them to include a transaction that spans multiple query requests (possibly something like an extended persistence context) in a JSE application.

But I am wondering if I can avoid sending the entityManager object throughout the service and DAO methods as an additional parameter using spring @PersistenceContext injection and mark the methods with @Transactional annotation to use a manual transaction with this entity manager.

I think I can somehow handle this using ThreadLocal for this function, but I will be happier if I can attach this to the spring structure.

This is an example of what I mean:


User Interface Action Method:

Here we see that the transaction begins with the ui logic, since the facade / command method is not used in the backend to group these calls into business logic:

Long transactionid = tool.beginTransaction(); // calling business methods tool.callBusinessLogic("purchase", "receiveGoods", paramObject1, transactionid); tool.callBusinessLogic("inventory", "updateInventory", paramObject2, transactionid); tool.commitTransaction(transactionid); 

Inside the tool:

 public Long beginTransaction() { // create the entity --> for the @PersistentContext Entitymanager entityManager = createEntityManagerFromFactory(); long id = System.currentTimeMillis(); entityManagerMap.put(id, entitymanager); // start the transaction --> for the @Transactional ? entityManager.getTransaction().begin(); return id; } public void commitTransaction(Long transactionId) { EntityManager entityManager = entityManagerMap.get(transactionId); entityManager.getTransaction().commit(); } public Object callBusinessLogic(String module, String function, Object paramObject, Long transactionid) { EntityManager em = entityManagerMap.get(transactionId); // ================================= // HOW TO DO THIS???? // ================================= putEntityManagerIntoCurrentPersistenceContext(em); return executeBusinessLogic(module, function, paramObject, transactionid); } 

And an example of a service method:

 public class Inventory { // How can i get the entityManager that been created by the tool for this thread ? @PersistenceContext private EntityManager entityManager; // How can i use the transaction with that transactionId ? @Transactional public void receiveGoods(Param param) { // ........ } } 

Anyway to achieve this?

Thanks!

+6
spring jpa
source share
3 answers

Spring processing @PersistenceContext annotation does almost what you need with one big difference: you always get an EntityManager with a transaction and Spring always introduces the same instance for the same thread, so you have a distribution view and don't have to worry about thread safety. But you will never get an extended context this way!
Believe me, Spring 3 and the extended persistence context do not mix well, perhaps this will change in Spring 3.1, but I'm afraid that it is not in their focus. If you want to use the extended persistence context, let Spring introduce an EntityManagerFactory (via the @PersistenceUnit annotation), and then create an EntityManager on its own. For distribution, you need to either pass the instance as a parameter, or save it to ThreadLocal yourself.

+9
source share

Indeed, in order to have an application-driven persistence context, you need to somehow β€œcrack” the @Transactional and @PersistenceContext infrastructure by providing them with their own strong> Entity Manager and don't let Spring create their own.

The key to achieving this is to play around with the TransactionSynchronizationManager class a bit to register your own Entity Manager in the local thread, Spring will use it to enter into the PersistenceContext .

It took me a while ago for my own application, and I developed a small Spring AOP-based architecture to manage an extended persistence context.

Details here: JPA / Hibernate Global conversation with Spring AOP

+3
source share

When setting up transactions through @Transactional, you must pass the configuration of your transactions to the annotation.
This is where you start your transaction and then hope that @Transactional will also be launched.
for more information, you'd better start reading http://static.springsource.org/spring/docs/2.5.x/reference/transaction.html => 9.5.6. Using @Transactional

0
source share

All Articles