【问题标题】:failed to lazily initialize a collection when no value in DB当 DB 中没有值时,无法延迟初始化集合
【发布时间】:2016-03-30 18:43:11
【问题描述】:

我想知道为什么我在尝试获取附加到对象的对象列表时遇到此异常,但是当列表为空时我得到惰性异常:

例如:

protected static final String hqlRequest = "select user from User as user";

final StringBuilder sbHqlRequest = new StringBuilder(hqlRequest);
sbHqlRequest.append(" left outer join fetch user.listeCondition as condition");     
sbHqlRequest.append(" left outer join fetch user.listeReponse as reponse");
sbHqlRequest.append(" left outer join fetch reponse.listeCat reponseCat");
sbHqlRequest.append(" left outer join fetch reponseCat.listeDomain listeDomain");
sbHqlRequest.append(" left outer join fetch reponse.listePlan reponsePlan");


sbHqlRequest.append(" where user.identifiant=? ");
return (User) session.createQuery(sbHqlRequest.toString()).setInteger(0, identifiant.intValue()).uniqueResult();

我在尝试访问 reponseCat.listeDomain 时变得很懒惰。在我的数据库中没有列表,但我在等待 null,而不是异常。

是我做错了什么还是 Hibernate 是这样工作的?

谢谢。

编辑: 例外:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: Cat.listeDomain - no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:191)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:183)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:48)
at org.hibernate.collection.PersistentSet.isEmpty(PersistentSet.java:118)
at org.apache.commons.collections.CollectionUtils.isEmpty(CollectionUtils.java:979)
at org.apache.commons.collections.CollectionUtils.isNotEmpty(CollectionUtils.java:992)

我注意到:当我使用传入参数的会话时,我得到了惰性异常,但是当我创建一个本地会话时它可以工作,但是我的对象与两个不同的会话相关联!!!

有人可以帮忙吗,我想完成这个以度过快乐的圣诞节:(

【问题讨论】:

标签: java hibernate lazy-loading


【解决方案1】:

此错误表明您在会话关闭时正在访问该字段。通常在延迟加载中会发生什么,因为在这种情况下事务是不同的。您最初可能只需要使用急切加载来加载它。

从以下相同的方法调用获取的集合的 size() 方法

User user = (User) session.createQuery(sbHqlRequest.toString()).setInteger(0, identifiant.intValue()).uniqueResult();
user.getListeDomain().size();
user.getListeCondition().size();
....
//other collections
return user;

【讨论】:

  • 这就是我无法理解的原因,会话从未关闭。否则我将无法获得所有其他收藏品和东西!
  • 一旦您进行查询并进一步移动,会话就会被休眠本身关闭。您可以在移动时做一件事,调用 listeDomain 上的 size() 方法,然后在执行查询的同一方法中获取用户对象。
  • 我不知道当我进一步移动时休眠会自行关闭会话,感谢您提供信息。但我仍然不明白我怎样才能获得其他收藏?同一个会话!
  • 一旦你有了用户对象,就在每个集合上调用 size() 函数,让我用同样的方法更新我的答案。
  • 调用size()方法再次抛出惰性异常!!
【解决方案2】:

当我遇到这个问题时,我必须执行一个单独的查询来查看该列表是否有任何结果。如果它没有任何结果,那么我使用new List<>(); 语句将一个空列表放入结果中。所以,例如:

List<> result = query.setParameter(0, owner.id).getResultList();
if ( result.size() > 0 ) 
    owner.setList(result);
else
    owner.setList(new List<>() );

这将删除标记为未初始化的休眠托管列表,因为数据库中没有该所有者的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 2016-06-04
    • 2018-11-21
    • 2014-12-23
    • 2020-05-10
    • 2020-03-18
    • 2021-03-13
    相关资源
    最近更新 更多