Java 强制预先加载其他延迟加载的属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3932227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 07:07:38  来源:igfitidea点击:

Force eager loading of otherwise lazy loaded properties

javahibernatelazy-loadingeager-loading

提问by

I've got a Hibernate object which's properties are all loaded lazy. Most of these properties are other Hibernate objects or PersistentSets.

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

Now I want to force Hibernate to eager load these properties for just one time.

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

Of course I could "touch" each of these properties with object.getSite().size()but maybe there's another way to achieve my goal.

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

采纳答案by Pascal Thivent

The documentation puts it like this:

文档是这样写的:

You can force the usual eager fetching of properties using fetch all propertiesin HQL.

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

References

参考

回答by dogbane

According to the hibernate docs, you should be able to disable lazy property loading by setting the lazyattribute on your particular property mappings:

根据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>

回答by matt b

Dozerworks well for this type of thing - you can ask Dozer to map the object to another instance of the same class, and Dozer will visit all objects reachable from the current object.

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

See this answer to a similar questionand my answer to another related questionfor more details.

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

回答by Joshua Grippo

This is slow, because it makes a round trip for every item it needs to initialize, but it gets the job done.

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

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);
        }
    }
}

回答by stephen.hanson

This is an old question, but I also wanted to point out the static method Hibernate.initialize.

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

Example usage:

用法示例:

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

The children are now initialized to be used even after the session is closed.

即使在会话关闭后,孩子们现在也被初始化为使用。

回答by oomer

For me this works:

对我来说这有效:

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

Rather than this:

而不是这样:

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

回答by user3073309

3 ways

3种方式

1.HQL with left join children

1.HQL 与左加入孩子

2.SetFetchMode after createCriteria

2.在createCriteria之后设置FetchMode

3.Hibernate.initialize

3.Hibernate.initialize