簡體   English   中英

Hibernate 本機 SQL 查詢 - 如何通過熱切初始化的一對多關聯獲取不同的根實體

[英]Hibernate native SQL query - how to get distinct root entities with eagerly initialized one-to-many association

我有兩個實體DeptEmp (實際情況已更改並已最小化)。 它們之間存在 1:n 的關聯,即屬性Dept.empListEmp.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]> ,其中DeptEmp (按該順序)在數組中的實例和正確初始化的字段Dept.empList 沒關系。

為了獲得不同的Dept ,我認為設置變壓器DISTINCT_ROOT_ENTITY (取消注釋該行)就足夠了。 不幸的是, DistinctRootEntityResultTransformer基於RootEntityResultTransformer將元組中的最后一個元素視為根實體(它是硬連線的)。 由於實體的順序是由addEntityaddJoin調用的順序決定的,因此轉換器錯誤地將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM