In the standalone application(single threaded command line tool) I am developing ,I use Spring +Hibernate.
It has DAO and Service layers and for DAOs I use HibernateDAOSupport.
The collections in domain model are lazy-loading.
Since for lazy-loading I need to keep the Session opended,I open session at start of my application using:
HibernateTemplate tmpl;
SessionFactoryUtils.initDeferredClose(tmpl.getSessionFactory());
//do file reads,parse CSV , persist objects (normally takes along time)
//
//Finally
SessionFactoryUtils.processDeferredClose(tmpl.getSessionFactory());
But during execution ,I get the error:
Exception in thread “main”
org.springframework.orm.hibernate3.HibernateSystemException:
Illegal attempt to associate a
collection with two open sessions;
nested exception is
org.hibernate.HibernateException:
Illegal attempt to associate a
collection with two open sessions
Caused by:
org.hibernate.HibernateException:
Illegal attempt to associate a
collection with two open sessions at
org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
at
org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43)
at
org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at
org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at
org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at
org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
at
org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:33)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at
org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:564)
at
org.hibernate.impl.SessionImpl.update(SessionImpl.java:552)
How to fix this?
at
org.hibernate.impl.SessionImpl.update(SessionImpl.java:544)
at
org.springframework.orm.hibernate3.HibernateTemplate$14.doInHibernate(HibernateTemplate.java:657)
at
org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:372)
at
org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:654)
at
org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:650)
at
com.bigg.nihonbare.common.dao.hibernate.CommonDAOImpl.updateFamily(CommonDAOImpl.java:40)
at
com.bigg.nihonbare.common.service.impl.CommonServiceImpl.updateFamily(CommonServiceImpl.java:55)
at
com.bigg.nihonbare.util.flow.DynaRowHibernateUpdateHandler.handleRow(DynaRowHibernateUpdateHandler.java:72)
NOTE : In my DAOs I only have used methods like;
return (Long) this.getHibernateTemplate().save(family);
return (Family) this.getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session
.createCriteria(Family.class);
criteria.add(Expression.eq("familyId", familyId));
if (criteria.list().size() > 0) {
return criteria.list().get(0);
}
return null;
}
});
Watch for
getHibernateTemplate().getSessionFactory().openSession()in your DAO, you might be ending up opening 2 sessions, since you lately switched to this architecture, I know it from your other previous question.Hint: Use
getSession()instead. This SpringSource Forum’s thread might be helpful.