Struts2 +完整休眠插件 - >会话已关闭? [英] Struts2 + Full Hibernate Plugin --> Session is Closed?

查看:111
本文介绍了Struts2 +完整休眠插件 - >会话已关闭?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与这个问题有关(答案没有真正到位):



我有相同的设置:Struts 2.2.3和struts2-fullhibernatecore-plugin-2.2.2-GA。我没有为Struts2和插件更改默认值。我使用的是MySQL,没有额外的连接池,一般来说没什么特别的。



我在Action中使用下面的代码:

  FeedGroup persistent = null; 
列表< FeedGroup> list = objectList =(List< FeedGroup>)session.createCriteria(FeedGroup.class)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.list(); (feedgroup.getId()!= 0)//新的

}
if(persistent!= null)
{
persistent.copyValuesFromOther(feedgroup);
session.update(persistent);
}
else
session.save(feedgroup);

返回列表;

仅在大约每10个案例中,这给我以下异常 ,这不会发生在我的代码中,但可能在插件提交事务之后。

  org.hibernate.SessionException :会议闭幕! 


org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1346)
abelssoft。 newspaper.actions.ActionHelper.prepare(ActionHelper.java:65)
com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:167)
com.opensymphony.xwork2.interceptor.MethodFilterInterceptor。截距(MethodFilterInterceptor.java:98)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
com.opensymphony。 xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
com.opensymphony.xwork2.interceptor.ExceptionMappingInterc eptor.intercept(ExceptionMappingInterceptor.java:187)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java: 52)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
org.apache.catalina。 core.StandardContextValve.invoke(StandardContextValve.java:164)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
org.apache .catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
org.apache.catalina.connector.CoyoteAdapter 。服务(CoyoteAdapter.java:399)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
$ org.apache.coyote.http11.Http11Protocol Http11ConnectionHandler.process(Http11Protocol .java:204)
org.apache.tomcat.util.net.JIoEndpoint $ SocketProcessor.run(JIoEndpoint.java:311)
java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java :886)
java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:619)

这是我的代码逻辑中的问题,还是与插件?如果后者,可以更改配置帮助吗?我想使用插件,因为它只是担心它不能可靠工作,或者我对数据库的理解太过原始,而我的代码需要重写; - )。

解决方案

好的,因为没有人有答案,我再次查看了问题和代码,并搜索了一下。




  • 事实1:直到Struts 2.1.6才支持插件,另外我使用了新的Tomcat 7,所以我猜想某些东西可能不适用于事实2:Hibernate论坛中的某位人士指出,如果您尝试访问会话而不是打开,则会出现此问题。

  • 一个新的
    Hibernate论坛:Session是关闭!(接近底部的解决方案) code> @session 和 @transaction 不能正常工作,或者我错误地使用了它们,因为它们在我的prepare方法中经常是空的,这是一个类,并且从中派生出所有的struts2操作:

      public abstract class ActionHelper extends ActionSupport implements Preparable,... 

    在这个类中,我使用了目前为止在所有其他项目(Struts 2.1.6和Tomcat 6)中通常可以使用的以下Annotations:

      @SessionTarget 
    Session db;
    @TransactionTarget
    交易交易;
    private FeedGroupDAO _feedGroupDao;

    在准备方法中,我有防御性编程代码,检查会话是否为空,然后替换它由当前的hibernate会话。问题是这个会话经常被关闭,如果你询问 if(!session.isOpen())



    因此,现在我在ActionHelper类的prepare方法中使用以下代码:

      public void prepare( )抛出异常{
    //使用会话和事务初始化DAO对象

    if(session == null)
    {
    session = com.googlecode.s2hibernate.struts2 .plugin.util.HibernateSessionFactory.getNewSession();
    if(!session.isOpen())
    throw new NullPointerException(修复代码:会话不在这里);

    transaction = session.beginTransaction();
    }
    _feedGroupDao = new FeedGroupDAO(session,transaction); //使用相同的会话/事务初始化更多DAO

    getNewSession() 插件的方法似乎在内部使用Hibernate的 openSession(),因此这似乎是来自Hibernate论坛的工作解决方案。此外,由于struts2-fullhibernate-plugin正在管理从静态 getNewSession()方法获得的会话和事务,因此它仍然支持OpenSessionInView模式。作为一个旁注,我试图摆脱防御性编程,尽快抛出异常; - )

    希望这可以帮到你。


    Related to this question (where the answer doesn't really get to the point):

    Hiberate with Struts2 - Use Full Hibernate Plugin or another method to close Sessions?

    I have the same setup: Struts 2.2.3 and the struts2-fullhibernatecore-plugin-2.2.2-GA . I have none of the defaults changed for Struts2 and for the Plugin. I'm using MySQL, no additional connection pooling, and nothing fancy in general.

    I use the following code in my Action:

    FeedGroup persistent = null;
    List<FeedGroup> list = objectList = (List<FeedGroup>) session.createCriteria(FeedGroup.class)
            .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
            .list();
    if (feedgroup.getId() != 0) // a new one
    {
        persistent = (FeedGroup) session.get(FeedGroup.class, id);
    }
    if (persistent != null)
    {
        persistent.copyValuesFromOther(feedgroup);
        session.update(persistent);
    }
    else
        session.save(feedgroup);
    
    return list;
    

    This gives me the following exception only in about every 10 cases or so, which doesn't happen in my code, but likely after the transaction got committed by the plugin.

    org.hibernate.SessionException: Session is closed!
    
    org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)
    org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1346)
    abelssoft.newspaper.actions.ActionHelper.prepare(ActionHelper.java:65)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:167)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498)
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    java.lang.Thread.run(Thread.java:619)
    

    Is it a problem in the logic of my code or is it a problem related to the Plugin? If the latter, can a configuration change help? I'd like to use the plugin as it is, I'm just worried that it doesn't work reliably or that my understanding of Database stuff is too primitive and that my code needs rewriting ;-).

    解决方案

    Okay, as noone's got an answer, I looked into the question and the code again and googled a bit.

    • Fact 1: The plugin is only supported till Struts 2.1.6, additionally I'm using the new Tomcat 7, so I guessed that something might just not work with the plugin.

    • Fact 2: Someone in a Hibernate Forum pointed out, that this problem can arise if you try to access the session instead of opening a new one: Hibernate Forum:Session is Closed! (solution near the bottom)

    It seem that fact 1 lead to the Annotations of @session and @transaction not working correctly, or I was using them wrong, as they were often null in my prepare method, which is such a class and from which all my struts2 actions are derived:

    public abstract class ActionHelper extends ActionSupport implements Preparable, ...
    

    In this class, I used the following Annotations that usually worked in all other projects so far (Struts 2.1.6 and Tomcat 6):

    @SessionTarget
    Session db;
    @TransactionTarget
    Transaction transaction;
    private FeedGroupDAO _feedGroupDao;
    

    In the prepare method, I had defensive programming code that checked if the session was null and then replaced it by the current hibernate session. The problem was that this session was often times closed, what you can find out if you ask if (!session.isOpen())

    Therefore now I use the following code in my prepare method in the ActionHelper class:

        public void prepare() throws Exception {
        // initialize DAO Objects with Session and Transaction
    
        if (session == null)
        {
            session = com.googlecode.s2hibernate.struts2.plugin.util.HibernateSessionFactory.getNewSession();
            if (!session.isOpen())
                throw new NullPointerException("Fix the code: session's not here");
    
            transaction = session.beginTransaction();
        }
        _feedGroupDao = new FeedGroupDAO(session,transaction); // init more DAOs with the same session/transaction
    

    The getNewSession() method of the plugin seems to use Hibernate's openSession() internally, therefore this seems to be the working solution from the Hibernate-forums. Additionally, this still supports the OpenSessionInView pattern as the struts2-fullhibernate-plugin is managing the session and transaction you got from the static getNewSession() method. As a sidenote, I try to move away from defensive programming to throwing exceptions as soon as possible ;-)

    Hope this could help you.

    这篇关于Struts2 +完整休眠插件 - &gt;会话已关闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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