Reputation: 312
I am using Spring + JPA + Hibernate in my project. The project is structured as below: - DAO layer - responsible to get data. DAO returns data in form of Model objects. - Service layer - Calls DAO and processes/transforms the (Model) data in form required by UI.
I am using @Transactional for methods on Service layer.
I am facing problem where sometimes I get "Session is closed" error while reading data from a Lazily loaded collection. Also I am not facing this problem consistently. I get this error sometimes while running from TestNG tests and also when the application is deployed as WAR.
I am pasting the exception I get while running the TestNG tests:
org.hibernate.SessionException: Session is closed! at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72) at org.hibernate.impl.SessionImpl.getBatcher(SessionImpl.java:305) at org.hibernate.loader.Loader.doQuery(Loader.java:854) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274) at org.hibernate.loader.Loader.loadEntity(Loader.java:2037) at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86) at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76) at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3268) at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:496) at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:477) at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227) at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:147) at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090) at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:1026) at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176) at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215) at 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) at 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) at java.lang.reflect.Method.invoke(Method.java:597) at 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) at 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) at 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) at 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) at java.lang.reflect.Method.invoke(Method.java:597) at org.testng.internal.MethodInvocationHelper.invokeHookable(MethodInvocationHelper.java:194) at org.testng.internal.Invoker.invokeMethod(Invoker.java:695) at 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) at java.lang.Thread.run(Thread.java:662)
This is my first project using Spring / JPA / Hibernate. I am not able to find out what may be causing this problem? Also what can be done to resolve this problem?
Please let me if some more information is required. Any help / pointers are highly appreciated :)
Upvotes: 2
Views: 1991
Reputation: 18639
When you are fetching Lazy objects you receives proxy objects instead of real one.
This is probably happened because you are trying to access not initiated Proxy object after your Transaction finished and session closed.
I believe you need to consider on of two options:
Seriously review your Transaction boundaries, and make sure that all your object operation happens inside those transaction boundaries. It will be something like "Open Session In View" design pattern.
Make all your collections EAGER
. In that case you will receive a lot of unnecessary database queries.
Hope it helps.
Upvotes: 1