10/19/2007

Mind thread-safety when injecting EntityManager

As I wrote in post Why we need type-level injections in JavaEE, injecting EJB 3 stateful beans into servlet instance fields is not thread-safe. Along the same line, injecting EntityManager with @PersistenceContext into servlet instance variables is not thread-safe, either. EntityManager is just not designed to be thread-safe.

For example, the following code snippet of a servlet class is incorrect:

public class FooServlet extends HttpServlet {
//This field injection is not thread-safe.
//FIXME
@PersistenceContext
private EntityManager em;
...
}
One way to fix this is to inject EntityManagerFactory instead. EntityManagerFactory is guaranteed to be thread-safe. For example:
public class FooServlet extends HttpServlet {
//This field injection is thread-safe
@PersistenceUnit
private EntityManagerFactory emf;

protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
EntityManager em = emf.createEntityManager();
//work with em
}
}