我收到了LazyInitializationException并且不确定原因。我将一个实体(具有id的BaseEntity)作为数据存储在primefaces树节点上,以使其成为动态的(即onNodeExpand事件处理程序从db获取扩展节点子节点)。我知道实体在渲染后变得分离,这就是为什么我在onNodeExpand中执行以下操作来添加子节点:
Product parentProduct = productService.findById(entity.getId());
这是返回一个我认为会“附加”的实体,但是当我迭代一个延迟加载的OneToMany关系时,我得到了LazyInitializationException:
for (Module module: parentProduct.getModules()) {
我在这里不明白?
修改
ProductService是一个@Stateless EJB,如下所示注入ViewScoped Bean:
@Named
@ViewScoped
public class MasterBean implements Serializable {
private static final long serialVersionUID = 3153934047649103375L;
TreeNode root;
@EJB
ProductRepo productService;
findById位于通用的CrudRepository中:
public E findById(final K id) {
return em.find(entityClass, id);
}
答案 0 :(得分:0)
如果您没有明确定义FetchType的Product和Modules之间存在OneToMany关系,那么获取类型by default is Lazy。如果是这种情况,那么你需要确保在Hibernate会话中迭代加载延迟的集合。
Hibernate会话有很多可以定义Hibernate会话的分界线,特别是当你使用库/框架时。我不熟悉primefaces,但如果你read up on Hibernate sessions here,你可能会看到Hibernate会话如何使用它。
答案 1 :(得分:0)
我遇到了与我正在开发的系统完全相同的问题。要解决此问题,您需要做的是获取包含该集合的对象,然后在同一会话中访问该集合,如下所示:
@Transactional
public User retrieveUser(String username)
{
User user = hibernateUserDao.getUserByUsername(username)
/*whatever your method of getting something from the database */
Collection collection = user.getCollection();
/*Then you can access and manipulate the collection object*/
}
这是因为如果你检索用户对象,默认情况下不会出于性能原因检索集合,但如果你在一个事务中全部执行,那么数据库连接仍然存在,所以hibernate会去检索实例你的收藏。
另一个缺陷是尝试在一个事务中检索用户,然后启动一个新用户来访问您的集合对象。 Hibernate不允许你这样做,它会引发类似的错误。
告诉我这是否有意义。
TL; DR:您必须检索父对象,然后在同一事务会话中访问您的集合对象。