Manage JPA Transactions in PlayFrameWork

1,595 views
Skip to first unread message

Ali Lotfdar

unread,
Jan 24, 2016, 8:21:30 PM1/24/16
to play-framework
Hello,
I am new in Play Framework. I am working on a project using Play+JPA. I was not aware that Play provide support for JPA.
Currently, I have annotated all my Actions with @Transactional. But except part that I fetch data from database, I provides EntityFactoryManager(Singleton) and  explicitly make EntityManager and open/commit transaction for interaction with database.(also, I defined connection pool max/min in persistence.xml)

My questions
If the way that I am using is right?
If I want to use Play JPA, how transactions are commit(  have to close EntityManager explicitly or Play will manage it form me)?
How play manage if a http request needs several insertion in database in the case of exception.
How connection pool is defined in Play framework?

Although, I try to study play framework website to understand my questions, I could not find a good reference that explain JPA in play framework.

Thank you.
 

Rajendra Prasad Gujja

unread,
Jan 25, 2016, 5:36:46 PM1/25/16
to play-framework
Hi Ali Lotfdar,

- Play supports JPA well, You can use "play.db.jpa.JPA" to get the "em()" or you can call "withTransaction" and Play will take care of committing/rollbacking the transaction.
- @Transactional internally calls the "withTransaction" method. It will also bind the entity manager to the "Http.Contenxt". If you have only one action with @Transactional and all you insertions are through this action, the committing and rollback will be taken  care off.
- By default Play comes with "HikariCP" connection pooling, you can use "maxConnectionsPerPartition" to set the maximum connections needed (more here https://www.playframework.com/documentation/2.4.x/SettingsJDBC), but you can use any other connection pooling library like c3p0.
- Regarding the documentation, Play website has good starting point, but you need to deep dive into coding few days (https://www.playframework.com/documentation/2.4.x/JavaJPA)

Hope this helps!

-Raj.
Message has been deleted

Ali Lotfdar

unread,
Jan 26, 2016, 12:22:17 AM1/26/16
to play-framework

Hi Rajendra Prasad Gujja,

Thank you very much your explanation is very helpful.
.Just could you please let me have answer of these questions:

-You mean that even if I call server classes, logic classes... in order to do several find, persist, update,... from an Action, all of these transaction with be managed automatically and
There is no need for commit transaction, close em, or using try/catch/final issue for any of them?
- Shall I use one em() from
play.db.jpa.JPA for all transactions, or I can make several ones without caring about managing them?
- What about if I want use
library c3p0, shall I add jar file inside my project, and where I have to put my configurations?
- In my program since I was not familiar with Play JPA although I put @Transaction on all my Actions, but I created Singleton connection EntityManagerRefactor and create entityManager for my transactions!
 Can this way be problematic?
-Could you please let me know what is the function of "withTransaction" in play?
- what happen if I want manage a part of program by myself like below code:
EntityManager em=JPA.em();
EntityTransaction entr = em.getTransaction();
try{
if(!entr.isActive())
  entr.begin();
  Tblrecordtypefields updateTblrecordtypes = em.find(Tblrecordtypefields.class,9);
  updateTblrecordtypes.setFieldlabel("JPATest");
  em.getTransaction().commit();
}finally
{
if(entr.isActive())
entr.rollback();
}

 

Just please consider that I use java in Play.
Sorry for asking a lot of these questions, I hope you have time for helping me.
Ali

Rajendra Prasad Gujja

unread,
Jan 26, 2016, 2:17:54 PM1/26/16
to play-framework
Hi Ali,

- Yes, if you have @Transactional on your action the flow starts from there to call multiple services or DAOs and everything is happening within that action, you don't need to worry about committing a transaction. @Transaction annotation will take care of that. You don't need to close the "em" too. You can use all the methods (like find) of "em" as usual.
- You just call "JPA.em()" to get the current em(), there will be one em bind to the current thread. (or if you have different persistent units, you call JPA.em(persistentUnit))
- If you want to use C3P0, you need to provide the Connection provide in persistence.xml (org.hibernate.connection.C3P0ConnectionProvider) and additional properties, this is nothing specific to Play! here, you can search JPA+C3P0 and have the correct configuration
- Play's JPA and JPAApi classes are good enough for most of the scenarios. You don't really need to create your own EMFactory unless you really need to. Try using JPA.em() or JPA.em(persistentUnit) in all the places
- "JPA.withTransaction()" wraps the block (or lambda) in a transaction. If you use @Transactional, you dont need to use this method. As @Transaction annotation is an action composition, you can use it only in controllers, in case if you need a new transaction somewhere else, you can make use of that method.

One more thing to remember in future, @Transactional is a thread bind, so it blocks your main(action) thread. You may need to avoid that by wrapping your calls in a Promise, but that is when you have a huge number of concurrent requests. You can search and read up on that.

Hope I helped a bit!

Thanks,
Raj.
Message has been deleted

Ali Lotfdar

unread,
Feb 15, 2016, 11:41:39 PM2/15/16
to play-framework
Hello Raj,

After your explanation I used Play JPA and everything is fine. Again thank you very much.
However, in my application  I need use two database connection, one for master(mainly write) and another for read(The data base are the same just one is replicate of another). I have Configured my application.conf and persistence.xml for both(default,second) And used @Transactional on my Action methods (Controller).
Could you please let me know is it fine if I use both of  JPA.em(default) and JPA.em(second) in one action? Does @Transaction manages all of them?
I encountered with no connection error when I just call an Action three times even if action just uses the JPA.em(second)?
Shall I do more in configurations?

(Please consider that I used @Transactional for all my action but inside them in case used both JPA.em(default) and JPA.em(second).
As I checked the status in Jprofile, in this way after about 3 times sending request, when I call my action, I see one of the thread is blocked for some seconds and I encounter with
no connection!

Thank you,
Ali

Rajendra Prasad Gujja

unread,
Feb 17, 2016, 1:38:57 PM2/17/16
to play-framework
Hi Ali,

It is great that you are making good progress.

With your scenario, I suspect it may create some problems. Two different EntityManagers within one transaction may cause issues (though I am not very clear on the what are the exact cases). I would suggest you use different transactions for each entity manager like JPA.em(default).withTransaction(()->{yourcode}) and JPA.em(second).withTransaction(()->{yourcode}). 

Please search "multiple entitymanagers" you may get some spring related search results, but Play is not different to understand the implications.

Thanks,
Raj.
Reply all
Reply to author
Forward
0 new messages