0

我想在我的 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();

在顶部打电话我有同样的例外。

4

1 回答 1

0

我认为同样的 awswer对这篇文章是有效的:

如果您的“工作单元”不能根据请求自动生成,我认为您可以使用事务在服务层中手动创建它。像这样的东西:

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 检索实体后从视图访问它,它将解释 LazyException,因为当您从视图访问对象时,您的 Hibernate 会话将已经关闭。

在您在 JSP/JSF 中使用模型时,您需要扩展工作单元以涵盖所有请求上下文。您必须包含一个过滤器来管理您的 Hibernate 会话打开,即所谓的 Open Session In view Pattern,看看这个。复制这篇文章中出现的过滤器实现并将其包含在您的应用程序中,它应该可以解决问题。

于 2012-09-07T11:12:33.507 回答