As described here (relevant parts),
https://www.playframework.com/documentation/1.3.x/jpa
Play will automatically start the Hibernate entity manager when it finds one or more classes annotated with the @javax.persistence.Entity annotation... When the JPA entity manager is started you can get it from the application code, using the JPA helper... Play will automatically manage transactions for you. It will start a transaction for each HTTP request and commit it when the HTTP response is sent.
As described here (relevant parts),
https://www.playframework.com/documentation/2.0/JavaJPA
There is no built-in JPA implementation in Play 2.0; you can choose any available implementation.. Every JPA call must be done in a transaction so, to enable JPA for a particular action, annotate it with @play.db.jpa.Transactional. This will compose your action method with a JPA Action that manages the transaction for you.
public static void meteoDeviceObjects() {
Query query = JPA.em("meteo").createQuery("FROM MeteoDeviceObject m");
List<MeteoDeviceObjectController> meteoDeviceObjects = query.getResultList();
renderJSON(meteoDeviceObjects);
}
public static void connectedClients(String connected) {
Query clientQuery = JPA.em("default").createQuery("FROM Client c WHERE c.connected=:connected");
List<Client> connectedClientsList = clientQuery.setParameter("connected", connected).getResultList();
renderJSON(connectedClientsList);
}Oops: PersistenceException An unexpected error occured caused by exception PersistenceException: org.hibern ate.exception.GenericJDBCException: Could not open connection
play.exceptions.UnexpectedException: Unexpected Error
at play.Invoker$Invocation.onException(Invoker.java:244)
at play.Invoker$Invocation.run(Invoker.java:306)
at Invocation.HTTP Request(Play!)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.Gener
icJDBCException: Could not open connection
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityMan
agerImpl.java:1387)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityMan
agerImpl.java:1310)
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException
(AbstractEntityManagerImpl.java:1397)
at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:62)
at play.db.jpa.JPA.withTransaction(JPA.java:230)
at play.db.jpa.JPA.withinFilter(JPA.java:195)
at play.db.jpa.JPAPlugin$TransactionalFilter.withinFilter(JPAPlugin.java
:299)
at play.Invoker$Invocation.withinFilter(Invoker.java:272)
at play.Invoker$Invocation.run(Invoker.java:289)
... 1 more
Caused by: org.hibernate.exception.GenericJDBCException: Could not open connecti
on ...
The JPA.em() method gets the current entity manager that's associated with the thread, it's intended for use with the @Transactional annotation. It will get whichever entity manager the annotation says, so if you say @Transactional(value = "mydb"), it will get the mydb entity manager. The @Transactional annotation manages these for you, so that's why there's no leak when you use the em() method.
JPA.em(String) however does not get the entity manager from the thread, it always gets a new entity manager, hence you need to make sure that you clean it up by calling em.close() when you're finished with it (usually in a finally block).
...
public static void update() {
Contact contact = new Contact ();
contact.FirstName = jsonContact.FirstName;
contact.LastName = jsonContact.LastName;
contact.Birthday = jsonContact.Birthday;
contact.Email = jsonContact.Email;
contact.Phone = jsonContact.Phone;
contact.Comment = jsonContact.Comment;
contact.save();
renderJSON(contact);
}
...@Transactional("NameOfRelevantEntityManagerHere")@Transactional("NameOfEntityManagerHere")
public static void update() {
Contact contact = new Contact ();
contact.FirstName = jsonContact.FirstName;
contact.LastName = jsonContact.LastName;
contact.Birthday = jsonContact.Birthday;
contact.Email = jsonContact.Email;
contact.Phone = jsonContact.Phone;
contact.Comment = jsonContact.Comment;
contact.save();
renderJSON(contact);
}@Transactional
public static void someAction() {
...
EntityManager entityManagerOne = JPA.em("NameOfEntityManagerOneHere");
try {
Query query = entityManagerOne.createQuery(...);
...
} finally {
entityManagerOne.close();
}
EntityManager entityManagerTwo = JPA.em("NameOfEntityManagerTwoHere");
try {
Query query = entityManagerTwo.createQuery(...);
...
} finally {
entityManagerTwo.close();
}
...
}