在Hibernate的运行时急于加载整个对象图 [英] Eager-load the whole object-graph at runtime in Hibernate

查看:69
本文介绍了在Hibernate的运行时急于加载整个对象图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在继续说在查询中指定获取类型"之前,请继续阅读.那不是我想要的.

Please read on before saying anything along the lines of "specify the fetch type in the query". That's not what I'm after.

我正在寻找一种渴望加载完整的对象图(对象+所有子对象及其所有子对象,依此类推)的方法.

I'm looking for a way to eager-load a complete object-graph (the object + all its children and all their children and so on).

不想枚举要加载的所有属性.我直到运行时才知道它们.

I do not want to enumerate all properties that are to be loaded. I don't know them until runtime.

N + 1个查询不是问题.但是,在此神奇操作结束时,我不想在图表中留下单个代理或惰性集合.

N+1 queries aren't a problem. But at the end of this magical operation, I don't want a single proxy or lazy collection left in my graph.

应该有可能编写一些反射性和递归地查看所有属性的代码.但是集合使这变得笨拙而复杂.

It should be possible to write a bit of code that reflectively and recursively looks at all properties. But collections make this awkward and complex.

有人推荐Dozer做这种事情,但这似乎有点过头了,所以我想把它保存为万不得已.

Some people have recommended Dozer for this kind of thing, but that seems a bit excessive, so I'd like to save that as a last resort.

推荐答案

我曾经需要类似的东西,因此我不得不使用反射来解决它.就我而言,我正在使用hql来检索记录.另外,这是我为急于加载定义为延迟加载的记录而创建的一种方法,因此您可能希望使第一种方法不查找FetchType.LAZY属性,而始终获取它.

I once needed something similar to that, and I had to use Reflection to solve it. In my case, I was using hql to retrieve the records. Also, this is an approach I created for eager loading records that are defined as lazy loading, so you may want to adapt the first method to not look for a FetchType.LAZY property and always fetch it regardless.

我构建的方法之一将准备"惰性获取.基本上有两种方法:对@ManyToOne使用hql上的左连接获取",对于@OneToMany和@ManyToMany使用hibernate.initialize().

One of the methods I built will "prepare" the lazy fetching. Basically two approaches: using "left join fetch" on the hql for @ManyToOne, and hibernate.initialize() for @OneToMany and @ManyToMany.

因此,第一个方法返回一个字符串,其中包含hql所需的"left john fetch" es,并且还建立了一个nToMany字段的列表,这些字段必须在执行查询后由Hibernate.initialize()调用. /p>

So, this first method returns a string with the required "left john fetch"es for the hql, and also builds a list of nToMany fields that have to be called by Hibernate.initialize() after the query is executed.

private String buildLazyFetch(Class<? extends GenericEntity> entityClass, List<String> nToManyFields) {
    String lazyFetches = new String();
    lazyFetches += " fetch all properties ";
    // iterate through all fields looking for lazy loaded relationships
    for (Field f : entityClass.getDeclaredFields()) {
        ManyToOne manyToOne = f.getAnnotation(ManyToOne.class);
        if (manyToOne != null) {
            if (manyToOne.fetch().equals(FetchType.LAZY)) {
                lazyFetches += " left join fetch t." + f.getName() + " ";
            }
        }
        OneToMany oneToMany = f.getAnnotation(OneToMany.class);
        if (oneToMany != null) {
            if (oneToMany.fetch().equals(FetchType.LAZY)) {
                nToManyFields.add(f.getName());
            }
        }
        ManyToMany manyToMany = f.getAnnotation(ManyToMany.class);
        if (manyToMany != null) {
            if (manyToMany.fetch().equals(FetchType.LAZY)) {
                nToManyFields.add(f.getName());
            }
        }
    }
    return lazyFetches;
}

,在执行hql之后,请致电:

and for after the hql is executed, call:

private void lazyFetchNToMany (List<String> nToManyFields, GenericEntity entity) {
    for (String field : nToManyFields) {
        try {
            Hibernate.initialize(BeanUtils.getProperty(entity, field));
        } catch (HibernateException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

我了解这并非您所期望的,但是如果您找不到所需的解决方案,它可能会对您有所帮助

I understand this is not exactly what you expected, but it might help you out in case you don't find your desired solution

这篇关于在Hibernate的运行时急于加载整个对象图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆