Hibernation: Session closed although it never closes (manually)

I have a really strange problem here, and I totally don’t understand why this is happening.

The problem looks like this:

I have a class called "SmampiAccount" that contains a list of email accounts. The mapping file looks like this (shortened):

<hibernate-mapping> <class name="com.smampi.web.model.account.SmampiAccount" table="SMAMPIACCOUNT"> <id name="id" type="long" access="field"> <column name="SMAMPI_ACCOUNT_ID" /> <generator class="native" /> </id> <bag name="mailAccounts" table="MAILACCOUNTS" lazy="false" inverse="true"> <key column="SMAMPI_ACCOUNT_ID"></key> <one-to-many class="com.smampi.web.model.mail.account.MailAccount"/> </bag> </class> </hibernate-mapping> 

I get instances of this class using this method:

 public SmampiAccount loadSmampiAccount(long id) throws FailedDatabaseOperationException { SmampiAccount smampiAccount = null; Session session = null; Transaction transaction = null; try { session = getSession(); transaction = session.beginTransaction(); smampiAccount = (SmampiAccount) session.load(com.smampi.web.model.account.SmampiAccount.class, id); List<MailAccount> mailAccounts = smampiAccount.getMailAccounts(); doSomething(mailAccounts); transaction.commit(); } catch (Exception e) { rollback(transaction); closeSession(); throw new FailedDatabaseOperationException(e); } finally { closeSession(); } return smampiAccount; } private Session getSession() { if (_session == null) { _session = getSessionFactory().openSession(); } if (_session.isOpen() == false) { _session = getSessionFactory().openSession(); } return _session; } 

It works great as it is.

Now I wanted to add a new property to the mapping file in order to keep the link to the default email account:

 <many-to-one name="defaultMailAccount" column="DEFAULT_MAIL_ACCOUNT_ID" /> 

Now I get an exception in the public method SmampiAccount loadSmampiAccount (long identifier) ​​in this line:

 List<MailAccount> mailAccounts = smampiAccount.getMailAccounts(); 

Stacktrace:

 org.hibernate.SessionException: Session is closed! at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72) at org.hibernate.impl.SessionImpl.getPersistenceContext(SessionImpl.java:1954) at org.hibernate.event.def.DefaultPostLoadEventListener.onPostLoad(DefaultPostLoadEventListener.java:49) at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:250) at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982) at org.hibernate.loader.Loader.doQuery(Loader.java:857) 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:3293) 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.smampi.web.model.account.SmampiAccount_$$_javassist_19.getMailAccounts(SmampiAccount_$$_javassist_19.java) 

How is this possible? The session is closed manually, and .commit() is not yet called (which usually closes the session). It is also not possible that a different method is used here, because I am creating a new hibernation session for each method call that is only for this method.


Edit

I added some debug information about the state of the open session:

 session = getSession(); System.err.println(session.isOpen()); transaction = session.beginTransaction(); // 1 (true) System.err.println(session.isOpen()); // 2 (true) smampiAccount = (SmampiAccount) session.load(com.smampi.web.model.account.SmampiAccount.class, id); System.err.println(session.isOpen()); // 3 (true) List<MailAccount> mailAccounts = smampiAccount.getMailAccounts(); // Throws exception that session is closed doSomething(mailAccounts); System.err.println(session.isOpen()); // 4 (not called) transaction.commit(); 

This gives me:

 true true true org.hibernate.SessionException: Session is closed! 
+4
source share
1 answer

I am the biggest idiot in the world.

In the defaultMailAccount installer, I had the following:

 public void setDefaultMailAccount(MailAccount defaultMailAccount) { this.defaultMailAccount = defaultMailAccount; try { databasecontroller.update(this); } catch (FailedDatabaseOperationException e) { handleException(e, false, null, null); } } 

A call to databasecontroller.update(this) caused a cascade whenever Hibernate tried to load a saved version from the database, and this again caused the session to close.

Moving the databasecontroller.update(..) call outside the method fixed the problem.

Sorry that everything is for your time and thanks for the help!

+2
source

All Articles