与此问题相关(答案并未真正达到目的):
Hiberate with Struts2 - Use Full Hibernate Plugin or another method to close Sessions?
我有相同的设置:Struts 2.2.3和struts2-fullhibernatecore-plugin-2.2.2-GA。我没有为Struts2和插件更改默认值。我正在使用MySQL,没有额外的连接池,一般都没什么特别的。
我在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;
这给了我以下异常仅在大约每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 :(得分:1)
好的,因为没有人得到答案,我再次查看了问题和代码并用Google搜索了一下。
事实1:插件只支持Struts 2.1.6,另外我使用的是新的Tomcat 7,所以我猜测插件可能无法正常工作。
事实2:Hibernate论坛中有人指出,如果您尝试访问会话而不是打开新会话,则会出现此问题:Hibernate Forum:Session is Closed!(解决方案)靠近底部)
似乎事实1导致@session
和@transaction
的注释无法正常工作,或者我使用它们是错误的,因为它们在我的准备方法中通常为空,这是一个类并且我的所有struts2动作都来自:
public abstract class ActionHelper extends ActionSupport implements Preparable, ...
在本课程中,我使用了以下通常在所有其他项目中工作的注释(Struts 2.1.6和Tomcat 6):
@SessionTarget
Session db;
@TransactionTarget
Transaction transaction;
private FeedGroupDAO _feedGroupDao;
在准备方法中,我有防御性编程代码,检查会话是否为空,然后由当前的hibernate会话替换它。问题是本次会议经常被关闭,如果你问if (!session.isOpen())
因此,现在我在ActionHelper类的prepare方法中使用以下代码:
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()
方法获得的会话和事务。作为旁注,我试图尽快从防御性编程转向抛出异常; - )
希望这可以帮到你。