2011-06-09 65 views
0

與此相關的問題(其中的答案並沒有真正去點):Struts2 +完整的Hibernate插件 - >會話關閉?

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

我有相同的設置:Struts的2.2.3和Struts2的-fullhibernatecore-插件-2.2.2 -GA。我沒有爲Struts2和插件更改默認值。我使用的是MySQL,沒有額外的連接池,一般來說沒有什麼奇特的。

我用下面的代碼在我的行動:

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; 

這使我有以下異常只在大約每10個案件或使,這並不在我的代碼發生,但有可能在後事務由插件提交。

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) 

這是我的代碼的邏輯問題還是它與插件有關的問題?如果後者,可以更改配置幫助嗎?我想使用插件,因爲它只是擔心它不能可靠工作,或者我對數據庫的理解太過原始,而且我的代碼需要重寫;-)。

+0

也許我應該補充說FeedGroup.copyValuesFromOther(feedgroup)只不過是將一些實例值從參數複製到這個feedgroup,而不改變id。 – Akku 2011-06-09 14:50:01

回答

1

好的,因爲沒有人得到答案,我再次查看問題和代碼,並搜索了一下。

  • 事實1:插件只支持至Struts的2.1.6,另外我使用的是新的Tomcat 7,所以我猜的東西可能只是無法與插件工作。

  • 事實2:有人在Hibernate的論壇上指出,如果你嘗試,而不是訪問會話的打開一個新可能會出現這樣的問題:Hibernate Forum:Session is Closed!(接近底部溶液)

看來事實1導致註釋@session@transaction無法正常工作,或者我錯誤地使用了它們,因爲它們在我的prepare方法中經常是空的,這是一個類,並且從中派生出我所有的struts2操作:

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

在這個類中,我用下面的註解,通常在所有其他項目迄今爲止的工作(Struts的2.1.6和Tomcat 6):

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

在準備方法,我有防禦性編程代碼檢查會話是否爲空,然後將其替換爲當前的休眠會話。問題是,這個會議時常關閉,你可以找到,如果你問if (!session.isOpen())

所以現在我用下面的代碼在我的準備方法在ActionHelper類:

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 

getNewSession()方法的插件似乎在內部使用Hibernate的openSession(),因此這似乎是來自Hibernate論壇的工作解決方案。此外,這仍然支持OpenSessionInView模式,因爲struts2-fullhibernate-plugin正在管理從靜態方法getNewSession()獲得的會話和事務。作爲一個旁註,我試圖擺脫防守編程,儘快拋出異常;-)

希望這可以幫助你。