在使用Hibernate Interceptor时,我应该在Struts2 Web应用程序中打开和关闭Hibernate会话

时间:2014-10-22 23:04:09

标签: java hibernate session struts2 interceptor

我在我的Struts2应用程序中为每个CRUD操作使用Hibernate Interceptor会话对象,因为我打开了Hibernate Interceptor实现对象的会话。

我希望在我的整个Struts2应用程序中每个请求只使用一个Hibernate会话。

为此,我在Struts Interceptor intercept()方法中打开了Hibernate会话,并在完成Struts Interceptor intercept()之前关闭了Hibernate会话。

但在我的应用程序中,我使用了“连锁动作”调用。如果我尝试在下一个链操作中使用Hibernate会话,那时我得到Session close Exception

请帮助我在Struts2应用程序中打开和关闭Hibernate Interceptor会话的地方。

拦截

public class MyStrutsInterceptor implements Interceptor {
  public void init() {
    // I created sessionfactroy object as a static variable 
  }

  public void destroy() {
    // I released the DB resources 
  }
  public String intercept(ActionInvocation invocation) throws Exception {
    Session session = sessionFactory().openSession(new MyHibernateInterceptor());
    invocation.invoke();
    session.close();
  }
}

Hibernate拦截器实现了类

public class MyHibernateInterceptor extends EmptyInterceptor{  
    //Override methods
}

当我使用链式操作时,调用invocation.invoke();session.close();语句被调用2次。

1 个答案:

答案 0 :(得分:0)

您可以将会话设置为ThreadLocal

private static final ThreadLocal<Session> threadLocal = new ThreadLocal<>();

private static Session getSession() throws HibernateException {
  Session session = threadLocal.get();

  if (session == null || !session.isOpen()) {
    session = sessionFactory.openSession();
    threadLocal.set(session);
  }

  return session;
}

private static void closeSession() throws HibernateException {
  Session session = (Session) threadLocal.get();
  threadLocal.set(null);

  if (session != null) {
    session.close();
  }
}

public String intercept(ActionInvocation invocation) throws Exception {
  Session session = getSession();
  String result;
  try {
    result = invocation.invoke();
  } finally {
    closeSession();
  }
  return result;
}