Hibernate 中的 LazyInitializationException:无法初始化代理 - 无会话

新手上路,请多包涵

我从我的服务中调用 dao

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

在 dao 中,我得到的产品是

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

这运行良好,但如果我将我的 dao 类更改为

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

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

原文由 Turtle 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 490
2 个回答

这是一个很好的 参考,可以让您熟悉 .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);
}

但是在你的第二种方法中,基本上没有任何初始化就返回了一个代理。会话在没有任何事先使用的情况下关闭。因此你得到了错误。

希望有帮助

原文由 Sohil 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

原文由 Vivek Goel 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题