我有两个实体Dept
和Emp
(实际情况已更改并最小化)。它们之间存在 1:n 的关联,即属性Dept.empList
,并Emp.dept
与各自的注释一起存在。我想使用本机 SQL 查询来获取List<Dept>
其元素是不同的并empList
热切地初始化集合。
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
没关系。
为了获得不同Dept
的 s,我认为设置变压器DISTINCT_ROOT_ENTITY
(取消注释该行)就足够了。不幸的是,DistinctRootEntityResultTransformer
它基于RootEntityResultTransformer
将元组中的最后一个元素视为根实体(它是硬连线的)。由于实体的顺序是由addEntity
,addJoin
调用的序列决定的,因此转换器错误地将Emp
其视为根实体并返回包含所有Emp
s 的所有Dept
s 的列表。
有没有什么干净的方法可以让 Hibernate 将其识别Dept
为根实体,即使它不是实体列表中的最后一个?
注 1:我尝试将 order 切换为.addJoin("e", "d.empList").addEntity("d", Dept.class)
. d.empList
由于需要d
定义,因此不起作用。HibernateSystemException : Could not determine fetch owner
在 Hibernate 内部(org.hibernate.loader.Loader
)的某个地方失败。
注 2:我试图将 order 定义为.addEntity("e", Emp.class).addJoin("d", "e.dept")
. 这看似有效,但该关联实际上仅从“多”方填充。因此,在请求之前,该集合Dept.empList
是一些未初始化的代理,它调用显式 SQL 查询,因此在我的查询中不使用连接。
注 3:寻找硬连线索引的自定义变压器有效:
.setResultTransformer(new BasicTransformerAdapter() {
public Object transformTuple(Object[] tuple, String[] aliases) {
return tuple[0];
}
public List transformList(List list) {
return DistinctResultTransformer.INSTANCE.transformList( list );
}
})
虽然我很犹豫接受这么简单的任务可能有这么复杂的解决方案。
Hibernate 版本:3.6.10(我知道 - 遗留项目 :-) 虽然我查看了最新版本的源代码,但似乎关键点没有不同)。