Requestfactory hibernate session-per-request

时间:2015-09-25 21:46:24

标签: hibernate gwt requestfactory

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

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

if(is_array($data)){
    foreach($data as $row){
        $sql = "INSERT INTO `table`( `title`, `content`, `category`) values";

        $title = mysql_real_escape_string( $row['title'] );
        $content = mysql_real_escape_string( $row['content'] );
        $category = mysql_real_escape_string( $row['category'] );

        $sql .= "('" . $title . "','" . $content, "','" $category "')";
        mysql_query($sql) or exit(mysql_error()); 
    }
}

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

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

我的web.xml:

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() {}  

}  

保存非常简单:

<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> 

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

1 个答案:

答案 0 :(得分:1)

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