如何通过热切初始化的一对多关联获取不同的根实体

如何通过热切初始化的一对多关联获取不同的根实体

本文介绍了Hibernate本机SQL查询-如何通过热切初始化的一对多关联获取不同的根实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个实体 Dept Emp (实际情况已更改并最小化).它们之间存在1:n的关联,即属性 Dept.empList Emp.dept 存在各自的注释.我想获取 List< Dept> ,其元素是不同的,并且使用本机SQL查询对集合 empList 进行了初始化.

I have two entities Dept and Emp (real case changed and minimized). There is 1:n association between them, i.e. properties Dept.empList and Emp.dept exist with respective annotations. I want to get List<Dept> whose elements are distinct and have collection empList eagerly initialized, using native SQL query.

session.createSQLQuery("select {d.*}, {e.*} from dept d join emp e on d.id = e.dept_id")
        .addEntity("d", Dept.class)
        .addJoin("e", "d.empList")
        //.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
        .list();

此查询返回 List< Object [2]> 和数组中的 Dept Emp 实例(按顺序),并且字段 Dept.empList 正确初始化.没关系.

This query returns List<Object[2]> with instances of Dept, Emp (in that order) in the array and field Dept.empList properly initialized. That's ok.

要获得独特的 Dept ,我认为设置转换器 DISTINCT_ROOT_ENTITY (取消注释该行)就足够了.不幸的是, DistinctRootEntityResultTransformer 是基于 RootEntityResultTransformer 的,后者将元组中的最后一个元素视为根实体(它是硬连线的).由于实体的顺序是由 addEntity addJoin 调用的顺序确定的,所以转换器错误地将 Emp 视为根实体,并返回所有 Dept 的code> Emp .

To get distinct Depts, I thought setting transformer DISTINCT_ROOT_ENTITY (uncommenting the line) would be enough. Unfortunately, the DistinctRootEntityResultTransformer is based on RootEntityResultTransformer which treats the last element in tuple as root entity (it's hardwired). Since the order of entities is determined by sequence of addEntity, addJoin calls, the transformer mistakenly treats Emp as root entity and returns list with all Emps of all Depts.

是否有任何干净的方法可以使Hibernate将 Dept 识别为根实体,即使它不在实体列表中也不是最后一个?

Is there any clean way how to make Hibernate recognized the Dept as root entity, even though it is not last in entity list?

注释1:我试图将顺序切换为 .addJoin("e","d.empList").addEntity("d",Dept.class).由于 d.empList 需要定义 d ,因此无法使用.出现 HibernateSystemException失败:无法确定Hibernate内部组件( org.hibernate.loader.Loader )中某个地方的获取所有者.

Note 1: I tried to switch order to .addJoin("e", "d.empList").addEntity("d", Dept.class). Does not work since d.empList requires d defined. Fails on HibernateSystemException : Could not determine fetch owner somewhere in Hibernate internals (org.hibernate.loader.Loader).

注释2:我试图将顺序定义为 .addEntity("e",Emp.class).addJoin("d","e.dept").这看似有效,但是实际上仅从许多"列表中填充关联.边.因此,集合 Dept.empList 是一些未初始化的代理,直到被请求为止,该代理将调用显式SQL查询,因此不会在我的查询中使用连接.

Note 2: I tried to define order as .addEntity("e", Emp.class).addJoin("d", "e.dept"). This seemingly works but the association is actually filled only from the "many" side. Hence the collection Dept.empList is some uninitialized proxy until requested, which invokes explicit SQL query and thus does not utilize the join in my query.

注释3:寻找硬接线索引的自定义转换器有效:

Note 3: The custom transformer looking for hard-wired index works:

        .setResultTransformer(new BasicTransformerAdapter() {
            public Object transformTuple(Object[] tuple, String[] aliases) {
                return tuple[0];
            }
            public List transformList(List list) {
                return DistinctResultTransformer.INSTANCE.transformList( list );
            }
        })

尽管我不愿接受这样简单的任务可能会有如此复杂的解决方案.

though I'm hesitant to accept such easy task could have such complicated solution.

休眠版本:3.6.10(我知道-遗留项目:-),尽管我调查了最新版本的源代码,但关键点似乎没有什么不同.

Hibernate version: 3.6.10 (I know - legacy project :-) though I looked into source code of latest version and seems the key points don't differ).

推荐答案

最后找到 https://stackoverflow.com/a/17210746/653539 -重复调用 .addEntity 以将根实体强制在列表末尾:

Finally found https://stackoverflow.com/a/17210746/653539 - make duplicate call of .addEntity to force root entity on the end of list:

    .addEntity("d", Dept.class)
    .addJoin("e", "d.empList")
    .addEntity("d", Dept.class)

它仍然可以解决,但比我的清洁,并且-基于36个投票-似乎是惯用的解决方案.

It's still workaround but cleaner than mine and - based on 36 upvotes - it seems as idiomatic solution.

这篇关于Hibernate本机SQL查询-如何通过热切初始化的一对多关联获取不同的根实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 03:58