我在我的项目中使用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的第一个项目。 我无法找出可能导致此问题的原因? 还有什么可以解决这个问题?
如果需要更多信息,请告诉我。 任何帮助/指针都非常感谢:)
答案 0 :(得分:1)
当您获取Lazy对象时,您会收到代理对象而不是真实代理对象。
这可能是因为您在事务完成和会话关闭后尝试访问未启动的Proxy对象。
我认为您需要考虑两个选项:
认真检查您的事务边界,并确保所有对象操作都发生在这些事务边界内。它将类似于“Open Session In View”设计模式。
制作所有藏品EAGER
。在这种情况下,您将收到许多不必要的数据库查询。
希望它有所帮助。