Requestfactory hibernate session-per-request [英] Requestfactory hibernate session-per-request

查看:95
本文介绍了Requestfactory hibernate session-per-request的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更新我的应用程序以使用每个请求会话模式,因此我可以移动到更新的GWT版本(我的实体不能正确保存过去的2.4版本 - GWT> 2.4 RequestFactory不保存子对象更改



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

  org.hibernate.HibernateException:如果没有活动事务,saveOrUpdate无效

我把大部分关于如何从 https://developer.jboss.org/wiki/OpenSessionInView 。以下是我的过滤器:

 <$ c $公开课Hiber nateSessionRequestFilter实现Filter {

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

私人SessionFactory sf;

public void doFilter(ServletRequest请求,
ServletResponse响应,
FilterChain链)
抛出IOException,ServletException {

try {
System.out.println(启动数据库事务);
sf.getCurrentSession()。beginTransaction();

//调用下一个过滤器(继续请求处理)
chain.doFilter(request,response);

//提交并清理
System.out.println(Committing the database transaction);
sf.getCurrentSession()。getTransaction()。commit();
$ b $ catch(StaleObjectStateException staleEx){
log.error(这个拦截器没有实现乐观并发控制!);
log.error(只有在您添加补偿措施后,您的申请才会生效!);
//回滚,关闭所有内容,可能会补偿对话期间的任何永久更改
//并最终重新开始业务对话。也许
//让应用程序的用户有机会将他的一些工作与
//新数据合并......您在这里所做的取决于您的应用程序设计。
throw staleEx;
} catch(Throwable ex){
//仅回滚
ex.printStackTrace();
if(sf.getCurrentSession()。getTransaction()。isActive()){
System.out.println(尝试在异常之后回滚数据库事务);
sf.getCurrentSession()。getTransaction()。rollback();

} catch(Throwable rbEx){
log.error(无法在异常后回滚事务!,rbEx);
}

//让其他人处理它......也许是另一个异常拦截器?
抛出新的ServletException(ex);


$ b $ public void init(FilterConfig filterConfig)throws ServletException {
System.out.println(Initializing filter ...);
System.out.println(从静态HibernateUtil单例中获取SessionFactory);
sf = HibernateUtil.getSessionFactory();

$ b $ public void destroy(){}


$ b $ $ pre $
$ b

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

保存非常简单:

 //客户端
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);
}

我可以提供的其他任何信息?我很欣赏任何想法或见解!

解决方案

每个请求需要一个会话,但不是一个单独的事务。在每种服务方法中打开和关闭事务,以防错误时的正确行为。


I am trying to update my application to use a session-per-request pattern so I can move to newer GWT versions (my entities don't save correctly past 2.4 - GWT >2.4 RequestFactory not saving child object changes

I have implemented a request filter, and it appeared to be working correctly - I can pull data down to the client no problem. However, when I try to save an entity, it errors out because it does not find an active transaction:

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

I pulled most of the info on how to implement this pattern from https://developer.jboss.org/wiki/OpenSessionInView . Here's my filter:

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

}  

My 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 save is very straightforward:

// 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);
}

Any other info I can provide? I appreciate any ideas or insight!

解决方案

You need one session per request, but not one single transaction. Open and close transactions in each service method, for proper behavior in case if error.

这篇关于Requestfactory hibernate session-per-request的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆