强制加载其他延迟加载的属性

时间:2010-10-14 10:32:11

标签: java hibernate lazy-loading eager-loading

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

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

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

7 个答案:

答案 0 :(得分:21)

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

使用示例:

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

现在,孩子们已经初始化,即使在会话结束后也可以使用。

答案 1 :(得分:7)

文档如下:

  

你可以强制通常的渴望获取   在HQL中使用fetch all properties的属性。

参考

答案 2 :(得分:3)

Dozer适用于此类事物 - 您可以要求Dozer将对象映射到同一个类的另一个实例,Dozer将访问从当前对象可到达的所有对象。

有关详细信息,请参阅this answer to a similar questionmy answer to another related question

答案 3 :(得分:1)

对我而言,这有效:

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

而不是:

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

答案 4 :(得分:1)

3种方式

1.HQL with left join children

在createCriteria

之后的

2.SetFetchMode

3.Hibernate.initialize

答案 5 :(得分: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);
        }
    }
}

答案 6 :(得分:-1)

根据hibernate docs,您应该可以通过在特定属性映射上设置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>