2014年11月19日 星期三

【筆記】在Servlet中直接存取EntityManager的建議方式

因為Servlet是預設在多執行緒環境中運行的,所以若在Servlet使用下列方式來注入EntityManager物件,是違反執行安全的(NOT thread-safe):
@PersistenceContext(unitName="QueryPaging")
private EntityManager em;
所以,若要在Servlet若要直接存取EntityManager的話,應該用本文(context)查找(lookup)的方式來取得EntityManager,再做相關的操作
package examples.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import examples.model.Employee;

@PersistenceContext(unitName="QueryPaging",name="myapp/QueryPaging")
@WebServlet("/EmAccessServlet")
public class EmAccessServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
       
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doPost(request, response);
 }

 @SuppressWarnings("unchecked")
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  PrintWriter pw = response.getWriter();
  try
  {
   EntityManager em = (EntityManager)new InitialContext()
                                        .lookup("java:comp/env/myapp/QueryPaging");
   List empList = em.createQuery("select e from Employee e").getResultList();
   for(Employee e : empList)
   {
    pw.println(e);
   }
  } catch (NamingException e)
  {
   e.printStackTrace();
  }
 }
}
使用上面的方式,對每個請求(request)都查找一個EntityManager,應用程式容器(container)會確保不會有相同的要求共享這些EntityManager

沒有留言: