Hibernate에서 "HTTP 요청 당 1 세션"패턴을 구현하려고하는데 첫 번째 요청에 대해 작동합니다. 서블릿의 doGet() 메소드가 열림 세션, 몇 가지 물건을 가져오고, 세션을 닫습니다.싱글 톤 DAO 인스턴스가 HTTP 트랜잭션 사이에 오래된 닫힌 세션을 유지합니다.
그러나 브라우저를 새로 고치면 My DAO Singleton 인스턴스 (생성자가 SessionFactory에서 세션을 가져옴)가 두 번째 호출되지만 여전히 이전 세션 객체 (싱글 톤 생성자가 다시 호출되지 않음)를 사용합니다. 그런 다음 "세션 닫힘"오류가 발생합니다.
나는 싱글 톤 인스턴스가 HTTP 요청 사이에서 캐시에 보관되어야한다고 생각한다. 다시 호출 된 DAO 싱글 톤 생성자를 어떻게 얻을 수 있습니까? (또는 다른 우아한 해결책은 신선한 SessionFactory에 세션 객체를 가지고하는?)
이
서블릿 대단히 감사합니다
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// Gets the session, eventually creates one
Session s = HibernateUtil.currentSession();
// Gets data from singleton DAO instance
MySingletonDAO o = MySingletonDAO.getInstance();
List<Stuff> stuff = o.getAllTheStuff();
// send it to the view
request.setAttribute("foo",stuff);
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(vue);
dispatcher.forward(request, response);
}
/* error handling blah blah */
finally {
// closing the session
HibernateUtil.closeSession();
}
MySingletonDAO.java :
public class MySingletonDAO {
// Usual singleton syntax
private static MySingletonDAO INSTANCE = new MySingletonDAO();
public static MySingletonDAO getInstance() { return INSTANCE;}
private Session session;
private MySingletonDAO() {
session = HibernateUtil.currentSession();
System.out.println("This constructor is called only on the first HTTP transaction");
}
public List<Stuff> getAllTheStuff() {
try {
session.beginTransaction();
Query q = session.createQuery("FROM StuffDBTable");
session.getTransaction().commit();
return (List<Stuff>) q.list();
}
}
}
고전 스레드 - 안전 HibernateUtil.java :
public class HibernateUtil {
private static final SessionFactory sessionFactory;
public static final ThreadLocal session = new ThreadLocal();
static {
try {
// Creates the SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (HibernateException he) {
throw new RuntimeException("Conf problem : "+ he.getMessage(), he);
}
}
public static Session currentSession() throws HibernateException {
Session s = (Session) session.get();
// Opens a new Session, if this Thread has none
if (s == null || !s.isOpen()) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
서비스 레이어는 내가 필요한 단서이며 왜 모델이 트랜잭션과 세션을 관리해야하는지 알 수 없습니다. 도움이되는 지침 (브라우저를 조금 읽은 후에)이 올바르게 처리되면 Servlet과 DAO 메소드 사이의 중간 계층 역할을하여 트랜잭션, 오류 및 반환 된 객체 처리와 같은 2 차적인 문제를 관리합니다. 향후 독자를 위해 큰 그림을 가져 오는 데 도움이되는 다음 링크를 제안 할 수 있습니다. https://msdn.microsoft.com/en-us/library/ee658090.aspx – Yow