JPA

Managing EntityManager without EJB / Dependence Injection

Posted on

source http://javanotepad.blogspot.sg/2007/08/managing-jpa-entitymanager-lifecycle.html

Managing EntityManager lifecycle when using JPA in a non enterprise environment (e.g. Tomcat) is a custom task you must take care of by yourself for you don’t have the IoC (Dependence Injection) of a Java EE 5 to manage the EntityManagerlifecycle. It happened the same when we discussed the EntityManagerFactory lifecycle in a previous post. Therefore, in this situation, you should consider the right scope of the EntityManager to use.

In order to decide your best approach, you need to keep in mind that:

  1. An EntityManager is not a heavyload object.
  2. It’s not safe to traverse lazy-loaded relationships once the EntityManager is closed (This situation will change as ofJPA 2.0).

Because of the first issue, there is no need to use the same EntityManger longer than needed, so there is neither room for application scope nor session scope. In addition to the first issue, note that you can’t use an EntityManager instance for the whole application lifecycle (application scope) for the EntityManager is not Thread-safe.

Only two scopes are left:

  • Method scope (i.e. instantiate/destroy one EntityManager in each business method).
  • Request scope.


Using EntityManager with method scope

You create and destroy the EntityManager instance within a business method.
Be careful to ensure the EntityManger is always closed. When dealing with transactions it could be a little tricky as it was commented in this post.

Dealing with this scope is easy, here is a sample:

public void aBusinessMethod() {

EntityManagerFactory emf = ... ;
EntityManager em = emf.createEntityManager();
try {
...
} finally {
em.close();
}
}

However, this method scope is not enough for every situation. There could be some scenarios where you’ll need a wide scope, such as the following situations:

  • When transactions spread multiple business methods.
  • Need to traverse lazy-loaded relationships outside a method (e.g. in a JSF page).

In these scenarios you can choose to keep one EntityManager for the whole life of a HTTP request as we are about to describe.

Before stepping further into the request scope strategy, you can think of a little workaround in order to avoid using the latter (this workaround is not my favorite alternative). It is based on forcing eagerly the loading of relationships of entities and can be useful when you need to traverse them once the EntityManager has been closed. One of such a typical scenario is traversing a relationship from within a JSF page.

Loading eagerly relationships

As a reminder, the JPA relationships that by default are lazily loaded are: OneToMany and ManyToMany.

Loading eagerly these relationships can be done in two different ways:

  • Changing the domain model
  • Explicit loading of relationships

The first one is referring to explicitly use the parameter fetch of the JPA annotation @OneToMany or @ManyToMany as in the sample:

@OneToMany(fetch=FetchType.EAGER)

The problem with this solution is that you define a requirement in your domain model instead of solving the problem just when you really need it.

Loading explicitly relationships can be done at first sight by invoking the method on the entity that get access to the collection of entities, however this is not very reliable: for instance, when we traverse a OneToMany relationship with Hibernate EM as the JPA engine, the returned collection (proprietary implementation) has not loaded its entities at all. In spite of returning a collection, its elements are not loaded till you really access each one (or invoke the size() method of the collection to force this loading)!

Using EntityManager with request scope

This is a one EntityManager per HTTP request strategy with the following features:

  • Creation on demand of the EntityManager.
  • Lazy closing of the EntityManager.

We’ll provide an on-demand creation of the EntityManager instance to use within the request service. So if theEntityManager is not needed for a given request, it won’t be create at all!

The main benefit of this scope is derived from the delayed closing of the EntityManager (it will last as long as a HTTP request is in process). Every queried entity will be managed till the end of the request and therefore during the presentation phase (the render phase in JSF for instance). This allows you to traverse lazy loaded relationships in a transparent manner: you no longer have to force the loading of relationships as commented before (they will be loaded only if they are traversed: on demand).

Another benefit is the possibility to share the EntityManager instance among several business methods within a request (with no need to pass the EntityManager as parameter). This is not a limitation, in case you would need more than oneEntityManager instance you’ll be able to bypass this utility and create directly an EntityManager instance yourself.

Transparent Design for an EntityManager with a lazy closing behaviorAs a requirement, our approach will be transparent from a client perspective.That is, the client code should not change in order to provided this behavior (this way, you can easily adapt your web application). This is the typical client code using the EntityManager inside a method:

EntityManagerFactory emf = ...
EntityManager em = emf.createEntityManager();
try {
...
} finally {
em.close();
}

In order to provide this transparency, we’ll create proxies for the EntityManagerFactory and EntityManager classes. The following UML class diagram, based on the Proxy Pattern, shows abstract proxies and the concrete classes:

Instead of creating one class for every proxy we have chose to create an abstract proxy class to be used as a generic multi-purpose base class, and we have provided the actual proxy as a concrete class extended from the the abstract proxy.

You can take a look to the EntityManagerFactoryProxy class:

abstract class EntityManagerFactoryProxy implements EntityManagerFactory {

protected final EntityManagerFactory delegate;

protected EntityManagerFactoryProxy(EntityManagerFactory emf) {

this.delegate = emf;
}

public EntityManager createEntityManager() {

return delegate.createEntityManager();
}

public EntityManager createEntityManager(Map map) {

return delegate.createEntityManager(map);
}

public boolean isOpen() {

return delegate.isOpen();
}

public void close() {

delegate.close();
}
}

The EntityManagerProxy class (not shown here, see complete source from resources) is created likewise.

The ScopedEntityManagerFactory class is just a factory for LazyCloseEntityManager. And LazyCloseEntityManager class acts in behalf of the client to override the EntityManager.close() method in order to delay calling the close method of its delegate (actual EntityManager).

Binding Thread and EntityManagerOur design is based on a property all Application Servers must ensure: for a given request, the ServletRequestListener‘s methods and Serlvet‘s service method are executed in the same thread (regardless of the use of a thread pool to serve requests).

Taking advantage from this issue, we’re going to create a request listener whose responsibility is just to close the EntityManager bound to to the request thread (if it was created previously created).

In order to delay the closing of the actual EntityManager we’ll encapsulate it in an LazyCloseEntityManager (transparent proxy) (whoseclose() method will be overridden) and we´ll bind the latter to the current request thread so that the actual EntityManager will be closed later by the request listener when the request service ends.

Binding the EntityManager to the current thread can be done easily using a ThreadLocal object.

The class responsible for creating LazyCloseEntityManager is ScopedEntityManagerFactory and so the one who useThreadLocal. when a client asks for an EntityManager managed ScopedEntityManagerFactory will look up first in itsThreadLocal object. If the current thread asking for the EntityManager has already used it, No other EntityManger will be created, otherwise, ScopedEntityManagerFactory will create a new LazyCloseEntityManager and will bind it to the thread for future uses.

Somehow ScopedEntityManagerFactory should be notified when the HTTP request finishes for it must forget theLazyCloseEntityManager bound to its ThreadLocal object.

One way to do so in a no coupled fashion is through a listenerScopedEntityManagerFactory will implementLazyCloseListener in order to be notified by the LazyCloseEntityManager.

Finally the HTTP request listener is responsible for closing eventually the LazyCloseEntityManager and notifying of this event.

The following UML class diagram exposes these ideas:

As a facility, we’ll show some of the core classes that implements this design.

We’ll start with the factory of LazyCloseEntityManager instances, that is ScopedEntityManagerFactory. This is the only class using the ThreadLocal class. Note it is notified when each LazyCloseEntityManager instance is really closed.

public class ScopedEntityManagerFactory extends EntityManagerFactoryProxy
implements LazyCloseListener {

private final ThreadLocal<LazyCloseEntityManager> threadLocal;

protected ScopedEntityManagerFactory(EntityManagerFactory emf) {

super(emf);
this.threadLocal = new ThreadLocal<LazyCloseEntityManager>();
}

public EntityManager createEntityManager(Map map) {

LazyCloseEntityManager em = threadLocal.get();
if (em == null) {
em = new LazyCloseEntityManager(super.createEntityManager(map));
createEntityManager(em);
}
return em;
}

public EntityManager createEntityManager() {

LazyCloseEntityManager em = threadLocal.get();
if (em == null) {
em = new LazyCloseEntityManager(super.createEntityManager());
createEntityManager(em);
}
return em;
}

private void createEntityManager(LazyCloseEntityManager em) {

threadLocal.set(em);
em.setLazyCloseListener(this);
}

protected LazyCloseEntityManager getEntityManager() {

return threadLocal.get();
}

public void lazilyClosed() {

threadLocal.set(null);
}
}

Below you can see the LazyCloseEntityManager class. Note this class is a wrapper for the Actual EntityManager: It is created by ScopedEntityManagerFactory (through a ThreadLocal) and used by the HTTP request listenerPersistenceAppRequestListener:

public class LazyCloseEntityManager extends EntityManagerProxy {

private LazyCloseListener listener;

public LazyCloseEntityManager(EntityManager delegate) {

super(delegate);
}

public void setLazyCloseListener(LazyCloseListener listener) {

this.listener = listener;
}

public LazyCloseListener getLazyCloseListener() {

return listener;
}

@Override
public void close() {
}

protected void lazyClose() {

super.close();
if (listener != null) listener.lazilyClosed();
}
}

The important thing to highlight is that the real close() method has no effect: in case a client code invoke this method, it has nothing to do. lazyClose() method is the one who close the actual EntityManager and is invoked by the HTTP request listener as you can see next.

Here is the HTTP request listener. Note it only closes the LazyCloseEntityManager bound to the current thread.

public class PersistenceAppRequestListener implements ServletRequestListener {

public void requestInitialized(ServletRequestEvent evt) {
}

public void requestDestroyed(ServletRequestEvent evt) {

PersistenceManager pm = PersistenceManager.getInstance();

if (pm instanceof ScopedPersistenceManager) {
LazyCloseEntityManager em = ((ScopedEntityManagerFactory)pm
.getEntityManagerFactory()).getEntityManager();

if (em != null)
em.lazyClose();
}
}
}

Client code using the request scope EntityManager

The only requirement (in addition to include the library jar file) for a client web application to use the request scopeEntityManager is:

  • Define a web listener.
  • Determine the name of the Persistence Unit to use (optional).

Both modifications must be done in your web.xml deployment descriptor archive.

Configuring the web.xml archive

The name of the Persistence Unit that you want for this utility to use can be define as an init parameter in the deployment descriptor file web.xml:

<context-param>
<param-name>es.claro.persistence.PERSISTENCE_UNIT</param-name>
<param-value>MyPersistenceUnit</param-value>
</context-param>

Alternatively, you can define the name of the Persistence Unit programmatically by using this code:

PersistenceManager.setPersistenceUnit("MyPersistenceUnit");

If no Persistence Unit name is define neither within the web.xml archive nor using this code, an default name is assumed, that is “DefaultPU”.

You also need to explicitly define a HTTP listener in the deployment descriptor file web.xml as follows:

<listener>
<description>Listener for managing EntityManager with request scope</description>
<listener-class>es.claro.persistence.PersistenceAppRequestListener</listener-class>
</listener>

Actually, this listener acts as a request listener and as a servlet context listener.
From an user perspective, this is the listener which lazily close the EntityManager of the current HTTP request, so it would be fatal to forget to define this listener.

Sample code

The only class to know is PersistenceManager.
Through this singleton, you can create the EntityManagerFactory instance needed to begin to work with JPA (What you’ll obtain from PersistenceManager won’t be actually an EntityManagerFactory object but a proxy subclass of this class).

Below is a sample code using this approach:

EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
EntityManager em = emf.createEntityManager();
try {
EntityTransaction t = em.getTransaction();
try {
t.begin();
...
t.commit();
} finally {
if (t.isActive()) em.getTransaction().rollback();
}
} finally {
em.close();
}

Note that this client code is the same for method scope, so switching between a scoped and non-scoped EntityManager strategy is completely transparent to the client code!

Simplifying client code

An optional enhancement to this design can be done.
Just to add PersistentManager.getScopedEntityManager() as as shortcut method.

By using this method in client code, closing the EntityManager each time you use it can be avoid

EntityManager em = PersistenceManager.getInstance().getScopedEntityManager();

try {
em.getTransaction().begin();
...
em.getTransaction().commit();
} finally {
if (em.getTransaction().isActive()) em.getTransaction().rollback();
}

Note this code is just trivial if no transaction is involved.

A little drawback for coding this way is that you no longer can switch between scoped and non-scoped EntityManagerstrategy without changing the client code!

Resources

The whole source code of the request scope entity manager has been developed with Netbeans and hosted as a little open source project at Google Code, so you can access both the source code as well as a jar file with the library ready to use.

Don’t use @PersistenceContext in a web app…

Posted on Updated on

source:http://weblogs.java.net/blog/ss141213/archive/2005/12/dont_use_persis_1.html 


I wrote an example web application that uses Java Persistence API. My servlet code looked like this:

public class RegistrationServlet extends HttpServlet {
// inject default EntityManager
@javax.persistence.PersistenceContext private EntityManager em;
@Resource private UserTransaction utx;
public void service ( HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
...
utx.begin();
em.persist(credential);
utx.commit();
...
}
...
}
This code worked, but only by chance. I did not realize that I have committed a horrible mistake in my servlet code. As the servlet spec suggests, unless explicitly mentioned in the deployment descriptor (web.xml) as SingleThreadModel, a single servlet instance by default can be shared to serve multiple requests concurrently. i.e. multiple threads can simultaneously enter the service() method of our servlet because we have not marked the service() assynchronized. As a result multiple threads will share the same PersistenceContext object via the instance variable em. A persistence context is not required to be thread safe as per the spec and is typically designed not to be used concurrently. Because the behavior is timing dependent and I had a tiny example, I did not see this issue during testing.
What is the fix
If we can’t use @PersistenceContext to inject an EntityManager, what is the fix? The fix is to either
use @PersistenceUnit to inject an EntityManagerFactory and use it to get hold of an EntityManager,
or
declare a dependency on an EntityManager and use JNDI to look it up.
The former one is called application managed entity manager because application manages the life cycle (by calling EntityManagerFactory.create & EntityManager.close) where as the later one is called container managed entity manager because container manages life cycle. More discussion on differences between container managed vs. application managed will be done in a later article. Let’s discuss the fix using both the approaches. Let’s discuss each approach using code samples.
Container Managed Entity Manager
There are a couple of ways to use JNDI lookup of entity manager:
a) via annotation:
@PersistenceContext(name="persistence/LogicalName", unitName="ActualPUNameAsItAppearsInPersistence.xml")
public class RegistrationServlet extends HttpServlet {
@Resource private UserTransaction utx;
public void service ( HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
Context envCtx = InitialContext().lookup("java:comp/env");
EntityManager em = (EntityManager) envCtx.lookup("persistence/LogicalName");
...
utx.begin();
em.persist(credential);
utx.commit();
...
}
...
}
Note that there is no injection going on here since the annotation @PersistenceContext appears at the class level. This is an alternative to declaring the persistence context dependency via a persistence-context-ref in web.xml as discussed below (in option #b).
b) via persistence-context-ref in web.xml
In web.xml, add an element like this:
 < persistence-context-ref>
< persistence-context-ref-name>
persistence/LogicalName
</persistence-context-ref>
< persistence-unit-name>
ActualPUNameAsItAppearsInPersistence.xml
</persistence-unit-name>
</persistence-context-ref>
Now do a JNDI lookup in your code as shown below:
public class RegistrationServlet extends HttpServlet {
@Resource private UserTransaction utx;
public void service ( HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
Context envCtx = InitialContext().lookup("java:comp/env");
EntityManager em = (EntityManager) envCtx.lookup("persistence/LogicalName");
...
utx.begin();
em.persist(credential);
utx.commit();
...
}
...
}
While using container managed entity manager (whether option #a or #b is used), we did not call em.close() because container is managing the life cycle of underlying persistence context. We also did not have to call utx.rollback() because web container would automatically rollback a transaction at the end of http request processing if servlet does not end the tx.
Application Managed Entity Manager
public class RegistrationServlet extends HttpServlet {
// inject EntityManagerfactory
@javax.persistence.PersistenceUnit private EntityManagerFactory emf;
@Resource private UserTransaction utx;
public void service ( HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
EntityManager em = emf.createEntityManager();
try {
...
utx.begin();
em.persist(credential);
utx.commit();
...
} catch (Exception e){
try {
utx.rollback();
} catch (Exception e) {}
} finally {
em.close();
}
}
...
}
See we call close() to close the EntityManager. More over note the use of try catch finally block. Since em.close() can not be called as long as the associated transaction is complete either by calling commit() or rollback(), we have to write those try catch finally.
Is it mentioned any where in the spec?
In Transaction Management chapter, section #4.2.3 of Java EE 5 proposed final draft spec, it is mentioned that:
In web components not implementing SingleThreadModel, transactional resource
objects should not be stored in class instance fields, and should be acquired
and released within the same invocation of the service method.
If you want to draw an analogy with JDBC world then EntityManager is like a Connection, where as EntityManagerFactory is like a DataSource. So EntityManager (or a PersistenceContext) which is a transactional resource should not be stored in a instance field and hence should not be injecte into a web app that does not implement SingleThreadModel.EntityManagerFactory is thread safe, so it can be injected into the servlet.
What is the performance over head?
Creation of a EntityManagerFactory is typically a costly operation. But creation of EntityManager is not. So creating an EntityManager is inside service() does not have negative impact on performance.
What about thread safety of UserTransaction?
If you see the code above, it still injects a UserTransaction object and stores in an instance field. That is not issue because it is a stateless object and can be shared across multiple threads. Looking at the javadocs for UserTransaction, it is clear that it by itself does not represent the transaction object, instead it is an interface to the underlying transaction manager to begin a new transaction and associate that with current thread; and end a transaction associated with current thread.