懒惰初始化休眠中的异常:无法初始化代理 - 无会话

2022-09-04 02:07:59

我从我的服务中调用道作为

@Override
@Transactional
public Product getProductById(int id) {
    return productDao.getProductById(id);
}

在道中,我得到的产品是

@Override
public Product getProductById(int id) {
    Product p = sessionFactory.getCurrentSession().load(Product.class, id);
    System.out.print(p);
    return p;
}

这运行正常,但如果我把我的道类更改为

@Override
public Product getProductById(int id) {
    return sessionFactory.getCurrentSession().load(Product.class, id);
}

我得到 org.hibernate.LazyInitializationException: 无法初始化代理 - 没有会话。例外情况发生在我刚刚打印产品的视图层中。我不明白为什么在dao方法中返回同一行会导致视图层中的异常,但是如果我将其保存在引用中然后返回,则可以正常工作。


答案 1

这里有一个很好的参考,让你熟悉.get()和.load()方法是如何工作的。

@Override
public Product getProductById(int id) {
    Product p = sessionFactory.getCurrentSession().load(Product.class, id);
    return p;
}

session.load()缺省情况下返回代理对象而不命中数据库。如果表上没有任何记录,它基本上会返回,否则它将返回一个引用,而无需填充实际对象,甚至不命中数据库。上面的方法返回一个代理,并且由于它还必须初始化您的对象,因此会话保持打开状态并填充对象。NoObjectFoundError

@Override
public Product getProductById(int id) {
    return sessionFactory.getCurrentSession().load(Product.class, id);
}

但是在第二种方法中,基本上返回代理而不进行任何初始化。此后,会话关闭,无需事先使用。因此,您会收到错误。

希望有所帮助


答案 2

此错误表示您正在尝试访问延迟加载的属性或集合,但休眠会话已关闭或不可用。Hibernate 中的延迟加载意味着在代码中访问属性/集合之前,不会填充对象(通过数据库查询)。Hibernate 通过创建一个动态代理对象来实现此目的,该对象仅在您首次使用该对象时才会命中数据库。为了使此功能正常工作,您的对象必须在其整个生命周期中附加到打开的休眠会话。

如果删除 SOP 语句,则根本不会访问对象,因此不会加载对象。当您尝试在代码的其他部分代码中访问它时,它将抛出LazyInitializationException。


推荐