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

Tur*_*tle 7 java spring hibernate

我通过服务将dao称为

@Override
@Transactional
public Product getProductById(int id) {
    return productDao.getProductById(id);
}
Run Code Online (Sandbox Code Playgroud)

在岛上,我得到的产品

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

运行正常,但如果我将dao类更改为

@Override
public Product getProductById(int id) {
    return sessionFactory.getCurrentSession().load(Product.class, id);
}
Run Code Online (Sandbox Code Playgroud)

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

Viv*_*oel 9

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

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


Soh*_*hil 5

这是一个很好的参考,可帮助您熟悉.get()和.load()方法的工作方式。

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

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

@Override
public Product getProductById(int id) {
    return sessionFactory.getCurrentSession().load(Product.class, id);
}
Run Code Online (Sandbox Code Playgroud)

但是在第二种方法中,基本上无需任何初始化即可返回代理。此后会话将关闭,无需任何事先使用。这样就得到了错误。

希望能有所帮助