In this previous post, I wrote about the danger of using field/setter injection to get EntityManager in servlets A follow-up post compares container-managed EntityManager vs application-managed EntityManager.
What if I need a container-managed EntityManager in my servlet class? There are 2 ways to do that:
1. type-level injection + JNDI lookup
@PersistenceContext(unitName="my-pu", name="persistence/em")
public class FooServlet extends HttpServlet {
@Resource private UserTransaction ut;
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
EntityManager em = null;
try {
Context ic = new InitialContext();
em = (EntityManager) ic.lookup
("java:comp/env/persistence/em");
} catch (NamingException e) {
throw new ServletException(e);
}
//call EntityManager methods inside transaction
try {
ut.begin();
Employee employee = new Employee(...);
em.persist(employee);
ut.commit();
} catch (Exception e) {
throw new ServletException(e);
}
}
}
2. web.xml + JNDI lookup
public class FooServlet extends HttpServlet {
@Resource private UserTransaction ut;
//the rest is the same as listed in bullet 1
The persistence-context-ref is declared in web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>FooServlet</servlet-name>
<servlet-class>com.foo.abc.FooServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FooServlet</servlet-name>
<url-pattern>/foo</url-pattern>
</servlet-mapping>
<persistence-context-ref>
<persistence-context-ref-name>persistence/em</persistence-context-ref-name>
<persistence-unit-name>my-pu</persistence-unit-name>
</persistence-context-ref>
</web-app>