Requestfactory 休眠会话每个请求

Requestfactory hibernate session-per-request

我正在尝试更新我的应用程序以使用按请求会话模式,这样我就可以转移到更新的 GWT 版本(我的实体在 2.4 之后无法正确保存 - GWT >2.4 RequestFactory not saving child object changes

我已经实现了一个请求过滤器,它似乎工作正常 - 我可以毫无问题地将数据下拉到客户端。但是,当我尝试保存一个实体时,它出错了,因为它没有找到活动事务:

org.hibernate.HibernateException: saveOrUpdate is not valid without active transaction

我从 https://developer.jboss.org/wiki/OpenSessionInView 中提取了有关如何实现此模式的大部分信息。这是我的过滤器:

public class HibernateSessionRequestFilter implements Filter {  

private static Log log = LogFactory.getLog(HibernateSessionRequestFilter.class);  

private SessionFactory sf;  

public void doFilter(ServletRequest request,  
                     ServletResponse response,  
                     FilterChain chain)  
        throws IOException, ServletException {  

    try {  
        System.out.println("Starting a database transaction");  
        sf.getCurrentSession().beginTransaction();  

        // Call the next filter (continue request processing)  
        chain.doFilter(request, response);  

        // Commit and cleanup  
        System.out.println("Committing the database transaction");  
        sf.getCurrentSession().getTransaction().commit();  

    } catch (StaleObjectStateException staleEx) {  
        log.error("This interceptor does not implement optimistic concurrency control!");  
        log.error("Your application will not work until you add compensation actions!");  
        // Rollback, close everything, possibly compensate for any permanent changes  
        // during the conversation, and finally restart business conversation. Maybe  
        // give the user of the application a chance to merge some of his work with  
        // fresh data... what you do here depends on your applications design.  
        throw staleEx;  
    } catch (Throwable ex) {  
        // Rollback only  
        ex.printStackTrace();  
        try {  
            if (sf.getCurrentSession().getTransaction().isActive()) {  
                System.out.println("Trying to rollback database transaction after exception");  
                sf.getCurrentSession().getTransaction().rollback();  
            }  
        } catch (Throwable rbEx) {  
            log.error("Could not rollback transaction after exception!", rbEx);  
        }  

        // Let others handle it... maybe another interceptor for exceptions?  
        throw new ServletException(ex);  
    }  
}  

public void init(FilterConfig filterConfig) throws ServletException {  
    System.out.println("Initializing filter...");  
    System.out.println("Obtaining SessionFactory from static HibernateUtil singleton");  
    sf = HibernateUtil.getSessionFactory();  
}  

public void destroy() {}  

}  

我的web.xml:

<servlet>
    <servlet-name>requestFactoryServlet</servlet-name>
    <servlet-class>com.example.server.util.ExampleRequestFactoryServlet</servlet-class>
    </servlet>

  <servlet-mapping>
    <servlet-name>requestFactoryServlet</servlet-name>
    <url-pattern>/gwtRequest</url-pattern>
  </servlet-mapping>

    <filter>  
      <filter-name>HibernateFilter</filter-name>  
      <filter-class>com.example.server.util.HibernateSessionRequestFilter</filter-class>  
    </filter>  

    <filter-mapping>  
      <filter-name>HibernateFilter</filter-name>  
      <url-pattern>/gwtRequest</url-pattern>  
    </filter-mapping> 

A保存很简单:

// client
private void saveScale(ScaleProxy scale) {
    scaleRequest.save(scale)
    .fire(new Receiver<Void>() {
        @Override
        public void onSuccess(Void response) {
            Window.alert("Scale saved.");
        }           
    });
}

// server
public static void save(Scale scale) {
    Session session = HibernateUtil.getSessionFactory().getCurrentSession();

    session.saveOrUpdate(scale);
}

我可以提供任何其他信息吗?我感谢任何想法或见解!

每个请求需要一个会话,而不是单个事务。在每个服务方法中打开和关闭事务,以便在出现错误时采取正确的行为。