繁体   English   中英

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

[英]LazyInitializationException in Hibernate : could not initialize proxy - no Session

我把我的服务称为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:无法初始化代理 - 没有Session。 我正在打印产品的视图层中发生异常。 我不明白为什么在dao方法中返回同一行导致视图层中的异常,但如果我将它保存在引用中然后返回它,则工作正常。

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

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

希望有所帮助

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

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

当您处理Hibernate和视图层时,这是一个典型的问题。 发生错误是因为在呈现视图之前Hibernate会话已关闭。 解决此问题的两种最简单方法是使用Open Session In View模式或在视图呈现之前获取视图中所需的所有数据。

由于您使用的是Spring,因此第一个解决方案是最简单的 - 只需应用OpenSessionInViewFilter (如果使用JPA,则应用OpenEntityManagerInViewFilter ):

http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.html http://docs.spring.io/spring/docs/current /javadoc-api/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.html

您还应该了解使用OSIV模式的优缺点。

在您的Product实体中,尝试在OneToMany关系注释中添加fetch = FetchType.EAGER,例如

@OneToMany(mappedBy =“employee”,fetch = FetchType.EAGER)

这将加载整个Product对象图,避免后续调用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM