我想在我的Web应用程序中使用Spring + Hibernate。 我的应用程序没有Spring编写。 当调用“打开页面”动作时,我打开Hibernate Session,将其存储在Http Session中并在我的DAO之间共享。当调用保存操作时,我使用旧会话启动事务。
但是现在我想将旧的DAO迁移到基于HibernateDaoSupport的DAO。 在这种情况下如何分享会话?如果我的DAO引用beans.xml中的一个SessionFactory它们会共享同一个会话吗? 在这种情况下如何管理会话(打开新的或使用旧的)?
我写了下面的代码,但是我得到了
org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话
在页面System.out.println(obj.getCategory()。getName());
public class CategoryObjectDAOSpringImpl extends HibernateDaoSupport implements CategoryObjectDAO {
@Override
public CategoryObject get(int id) throws Exception {
CategoryObject obj = getHibernateTemplate().get(CategoryObject.class, id);
System.out.println(obj.getId());
System.out.println(obj.getCategory().getName());
for (ObjAttrCommon objAttr : obj.getAttributes()) {
//objAttr.setSession(getSession());
System.out.println(objAttr.getId());
}
return obj;
}
如果我添加
,这很奇怪getSessionFactory().openSession();
在顶部打电话我有相同的例外。
答案 0 :(得分:0)
我认为same awswer对此帖有效:
如果您的“unit of work”无法按请求自动生成,我认为您可以使用交易在服务层中手动创建它。像这样:
public Object serviceMethod(params) {
TransactionTemplate transactionTemplate = getHibernateTemplate().get(CategoryObject.class, id);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus status) {
try {
// call your DAO's to update/delete/... and set values to service
} catch (DAOException e) {
LOGGER.error(e);
throw new ServiceException(e);
}
}
});
}
已编辑:因此异常会在事务中出现异常。确保问题不在您的视图中。如果在使用HibernateTemplate检索你的entites后,你将从视图中访问它,它将解释LazyException,因为当你从视图访问你的对象时,你的Hibernate会话将已经关闭。
在JSP / JSF中使用模型时,需要扩展工作单元以覆盖所有请求上下文。您必须包含一个管理Hibernate会话开放的过滤器,在视图模式中称为Open Session,take a look at this。 复制此帖子中显示的过滤器实现并将其包含在您的应用程序中,它应该可以解决问题。