Spring HibernateDaoSupport保持相同的Session?

时间:2010-01-28 06:32:21

标签: java hibernate spring

在我正在开发的独立应用程序(单线程命令行工具)中,我使用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;
                    }
});

2 个答案:

答案 0 :(得分:3)

在您的DAO中关注getHibernateTemplate().getSessionFactory().openSession(),您最近可能会打开2个会话,因为您最近切换到此架构,我从您之前的其他问题中了解到这一点。

提示:改为使用getSession()。这个SpringSource Forum's thread可能会有所帮助。

答案 1 :(得分:0)

每个线程分别关联很多会话.session不是 共享变量但是sessionfactory是,如果你将sessionfactory注入DAO,会由spring容器创建会话。