[英]Hibernate native SQL query - how to get distinct root entities with eagerly initialized one-to-many association
我有兩個實體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
,我認為設置變壓器DISTINCT_ROOT_ENTITY
(取消注釋該行)就足夠了。 不幸的是, DistinctRootEntityResultTransformer
基於RootEntityResultTransformer
將元組中的最后一個元素視為根實體(它是硬連線的)。 由於實體的順序是由addEntity
、 addJoin
調用的順序決定的,因此轉換器錯誤地將Emp
視為根實體並返回包含所有Dept
的所有Emp
的列表。
有沒有什么干凈的方法可以讓 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(我知道 - 遺留項目:-) 雖然我查看了最新版本的源代碼,但似乎關鍵點沒有區別)。
最后找到https://stackoverflow.com/a/17210746/653539 - 重復調用.addEntity
以強制在列表末尾的根實體:
.addEntity("d", Dept.class)
.addJoin("e", "d.empList")
.addEntity("d", Dept.class)
它仍然是解決方法,但比我的更干凈 - 基於 36 次投票 - 它似乎是慣用的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.