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
@Transactional
annotated method in a controller // must be in the controller) - grab the
EntityManager
instance 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
EntityManager
is used when I doJPA.em()
- What
EntityManager
is used when I doJPA.em("default")
// "default" seems to be so far the only key that works with this... - What
EntityManager
is 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
?