Struts2 + Full Hibernate Plugin --> Session is Closed?

随声附和 提交于 2019-12-09 01:59:27

问题


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 ;-).


回答1:


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.



来源:https://stackoverflow.com/questions/6294764/struts2-full-hibernate-plugin-session-is-closed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!