The documentation for using JPA in playframework is rather sparse.
All there is, from the following page,
https://www.playframework.com/documentation/2.4.x/JavaJPA
is a simple example of a persistence.xml and other basic configurations that must be done before it can be used at all.
However, how to use the EntityManager, is not very details.
In various examples on the web, I've come across three ways to get at an EntityManager:
JPA.em()JPA.em(String key)
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("defaultPersistenceUnit");
EntityManager em = entityManagerFactory.createEntityManager();
// where the string 'defaultPersistenceUnit' corresponds to the persistence-unit name in my persistence.xml file.
If I use JPA as play seems to intend, I
- have a
@Transactionalannotated method in a controller // must be in the controller) - grab the
EntityManagerinstance fromJPA.em()// not the other method which takes String key. That's the wrong one! - perform my operation. End.
OK. That works fine.
@Transactional
public Result addPerson()
{
Person person = Form.form(Person.class).bindFromRequest().get();
EntityManager em = JPA.em();
persist(em, person); // 'persist' is my static helper method
return redirect(routes.Application.index());
}
However, I'd like to understand the;
- life of an
EntityManager - What
EntityManageris used when I doJPA.em() - What
EntityManageris used when I doJPA.em("default")// "default" seems to be so far the only key that works with this... - What
EntityManageris used when I do
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("defaultPersistenceUnit");
EntityManager em = entityManagerFactory.createEntityManager();
- Why doesn't the key used in both methods from 3 and 4 correspond?
The documentation for the class JPA specifies
public static javax.persistence.EntityManager em(java.lang.String key)
Get the EntityManager for specified persistence unit for this thread.
https://www.playframework.com/documentation/2.4.x/api/java/index.html
So I would have assumed that key would/could/should correspond to the value of the name attribute of the persistence-unit element (in persistence.xml). i.e.,
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="defaultPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>DefaultDS</non-jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- can be create/validate/update/create-drop -->
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
So, while I have this working, it still feels a bit like magic. I guess I have to debug the Play code itself? So long as I stick to initiating the transaction from the controller only (as evidently intended) I guess I should have no problems.... with the life-cycle of the EntityManager... with cleaning up database resources etc.
But I guess there could be situations coming up where I need an EntityManager in some other context?
Then what do I use?
What is the best-practice life of an EntityManager in the context of a Playframework (or otherwise) web application?
The life of a request? The life of the application? Or something dynamically in between? What is playframework doing with its own managed EntityManager?