在我正在开发的独立应用程序(单线程命令行工具)中,我使用Spring + Hibernate。 它有DAO和服务层,对于DAO我使用HibernateDAOSupport。 域模型中的集合是延迟加载的。
由于延迟加载我需要保持会话开放,我在应用程序启动时打开会话:
HibernateTemplate tmpl;
SessionFactoryUtils.initDeferredClose(tmpl.getSessionFactory());
//do file reads,parse CSV , persist objects (normally takes along time)
//
//Finally
SessionFactoryUtils.processDeferredClose(tmpl.getSessionFactory());
但在执行期间,我收到错误:
线程“main”中的异常 org.springframework.orm.hibernate3.HibernateSystemException: 非法企图关联a 收集两个公开会议; 嵌套异常是 org.hibernate.HibernateException: 非法企图关联a 两次公开会议的集合 引起: org.hibernate.HibernateException: 非法企图关联a 收集两个公开会议在 org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410) 在 org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43) 在 org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101) 在 org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61) 在 org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55) 在 org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123) 在 org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293) 在 org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223) 在 org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:33) 在 org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) 在 org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:564) 在 org.hibernate.impl.SessionImpl.update(SessionImpl.java:552)
如何解决这个问题?
在 org.hibernate.impl.SessionImpl.update(SessionImpl.java:544) 在 org.springframework.orm.hibernate3.HibernateTemplate $ 14.doInHibernate(HibernateTemplate.java:657) 在 org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:372) 在 org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:654) 在 org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:650) 在 com.bigg.nihonbare.common.dao.hibernate.CommonDAOImpl.updateFamily(CommonDAOImpl.java:40) 在 com.bigg.nihonbare.common.service.impl.CommonServiceImpl.updateFamily(CommonServiceImpl.java:55) 在 com.bigg.nihonbare.util.flow.DynaRowHibernateUpdateHandler.handleRow(DynaRowHibernateUpdateHandler.java:72)
注意:在我的DAO中,我只使用了像
这样的方法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;
}
});
答案 0 :(得分:3)
在您的DAO中关注getHibernateTemplate().getSessionFactory().openSession()
,您最近可能会打开2个会话,因为您最近切换到此架构,我从您之前的其他问题中了解到这一点。
提示:改为使用getSession()
。这个SpringSource Forum's thread可能会有所帮助。
答案 1 :(得分:0)
每个线程分别关联很多会话.session不是 共享变量但是sessionfactory是,如果你将sessionfactory注入DAO,会由spring容器创建会话。