25

我有一个 Hibernate 对象,它的属性都是惰性加载的。这些属性中的大多数是其他 Hibernate 对象或 PersistentSet。

现在我想强制 Hibernate 一次性加载这些属性。

当然,我可以“触摸”这些属性中的每一个,object.getSite().size()但也许还有另一种方法可以实现我的目标。

4

7 回答 7

22

这是一个老问题,但我也想指出静态方法Hibernate.initialize

示例用法:

Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());

现在,即使在会话关闭后也可以使用子级。

于 2012-03-14T21:44:53.110 回答
7

文档是这样写的:

fetch all properties您可以在 HQL中强制使用通常的急切获取属性。

参考

于 2010-10-14T13:24:29.290 回答
3

Dozer非常适合这种类型的事情——您可以要求 Dozer 将对象映射到同一类的另一个实例,并且 Dozer 将访问从当前对象可访问的所有对象。

有关更多详细信息,请参阅此对类似问题的回答和我对另一个相关问题的回答。

于 2010-10-14T11:47:21.823 回答
1

对我来说,这有效:

Person p = (Parent) sess.get(Person.class, id);
Hibernate.initialize(p.getChildren());

而不是这样:

Person p = sess.createCriteria(Person.class, id);
Hibernate.initialize(p.getChildren());
于 2013-07-26T00:28:26.483 回答
1

3种方式

1.带有左连接子项的HQL

2.createCriteria后的SetFetchMode

3.休眠.初始化

于 2017-02-02T13:11:42.360 回答
0

这很慢,因为它对需要初始化的每个项目进行往返,但它完成了工作。

private void RecursiveInitialize(object o,IList completed)
{
    if (completed == null) throw new ArgumentNullException("completed");

    if (o == null) return;            

    if (completed.Contains(o)) return;            

    NHibernateUtil.Initialize(o);

    completed.Add(o);

    var type = NHibernateUtil.GetClass(o);

    if (type.IsSealed) return;

    foreach (var prop in type.GetProperties())
    {
        if (prop.PropertyType.IsArray)
        {
            var result = prop.GetValue(o, null) as IEnumerable;
            if (result == null) return;
            foreach (var item in result)
            {
                RecursiveInitialize(item, completed);
            }
        }
        else if (prop.PropertyType.GetGenericArguments().Length > 0)
        {
            var result = prop.GetValue(o, null) as IEnumerable;
            if (result == null) return;
            foreach (var item in result)
            {
                RecursiveInitialize(item, completed);
            }
        }
        else
        {
            var value = prop.GetValue(o, null);
            RecursiveInitialize(value, completed);
        }
    }
}
于 2010-12-08T02:53:33.077 回答
-1

根据休眠文档,您应该能够通过lazy在特定属性映射上设置属性来禁用延迟属性加载:

<class name="Document">
  <id name="id">
    <generator class="native"/>
  </id>
  <property length="50" name="name" not-null="true"/>
  <property lazy="false" length="200" name="summary" not-null="true"/>
  <property lazy="false" length="2000" name="text" not-null="true"/>
</class>
于 2010-10-14T10:59:01.367 回答