有时会出现“会话已关闭”的异常

时间:2012-04-28 05:59:35

标签: spring hibernate jpa

我在我的项目中使用Spring + JPA + Hibernate。 该项目的结构如下: - DAO层 - 负责获取数据。 DAO以Model对象的形式返回数据。 - 服务层 - 调用DAO并以UI所需的形式处理/转换(模型)数据。

我在服务层使用@Transactional方法。

我有时遇到问题"会话已关闭"从Lazily加载的集合中读取数据时出错。 我也不是一直面对这个问题。 从TestNG测试运行时以及将应用程序部署为WAR时,我有时会收到此错误。

我正在粘贴运行TestNG测试时遇到的异常:

org.hibernate.SessionException:会话已关闭!     at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)     在org.hibernate.impl.SessionImpl.getBatcher(SessionImpl.java:305)     在org.hibernate.loader.Loader.doQuery(Loader.java:854)     在org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)     在org.hibernate.loader.Loader.loadEntity(Loader.java:2037)     在org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86)     在org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76)     在org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3268)     at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:496)     在org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:477)     在org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227)     在org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:147)     在org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090)     在org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:1026)     在org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176)     在org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)     在org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)     at com.applications.qi.etplugin.et.model.impl.ETTestCasePackage _ $$ _ javassist_21.getVertical(ETTestCasePackage _ $$ _ javassist_21.java)     在com.applications.qi.etplugin.et.model.impl.ETTestCasePackage.getVertical(ETTestCasePackage.java:78)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)     在java.lang.reflect.Method.invoke(Method.java:597)     在org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:197)     at com.applications.qi.etplugin.et.model.impl.ETTestCasePackage _ $$ _ javassist_21.getVertical(ETTestCasePackage _ $$ _ javassist_21.java)     在com.applications.qi.etplugin.et.dao.impl.TestCaseDAOTest.Test2(TestCaseDAOTest.java:62)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)     在java.lang.reflect.Method.invoke(Method.java:597)     at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)     at org.testng.internal.MethodInvocationHelper $ 1.runTestMethod(MethodInvocationHelper.java:182)     在org.springframework.test.context.testng.AbstractTestNGSpringContextTests.run(AbstractTestNGSpringContextTests.java:158)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)     在java.lang.reflect.Method.invoke(Method.java:597)     at org.testng.internal.MethodInvocationHelper.invokeHookable(MethodInvocationHelper.java:194)     在org.testng.internal.Invoker.invokeMethod(Invoker.java:695)     在org.testng.internal.Invoker.invokeTestMethod(Invoker.java:894)     at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1219)     at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)     at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)     at java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java:886)     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:908)     在java.lang.Thread.run(Thread.java:662)

这是我使用Spring / JPA / Hibernate的第一个项目。 我无法找出可能导致此问题的原因? 还有什么可以解决这个问题?

如果需要更多信息,请告诉我。 任何帮助/指针都非常感谢:)

1 个答案:

答案 0 :(得分:1)

当您获取Lazy对象时,您会收到代理对象而不是真实代理对象。

这可能是因为您在事务完成和会话关闭后尝试访问未启动的Proxy对象。

我认为您需要考虑两个选项:

  1. 认真检查您的事务边界,并确保所有对象操作都发生在这些事务边界内。它将类似于“Open Session In View”设计模式。

  2. 制作所有藏品EAGER。在这种情况下,您将收到许多不必要的数据库查询。

  3. 希望它有所帮助。