0

私は2つのエンティティDeptEmp(実際のケースを変更して最小化しました)を持っています。それらの間には 1:n の関連付けがあります。つまり、プロパティDept.empListEmp.deptそれぞれの注釈が存在します。List<Dept>ネイティブ SQL クエリを使用して、どの要素が明確で、コレクション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]>(この順序で) を返します。それで大丈夫です。DeptEmpDept.empList

明確な s を取得するには、transformer を設定する(行のコメントを外す) だけで十分Deptだと思いました。DISTINCT_ROOT_ENTITY残念ながら、はタプルの最後の要素をルート エンティティとして扱うことにDistinctRootEntityResultTransformer基づいています (ハードワイヤードです)。RootEntityResultTransformerエンティティの順序はaddEntity,addJoin呼び出しのシーケンスによって決定されるため、トランスフォーマーは誤っEmpてルート エンティティとして処理し、すべてEmpの のすべての を含むリストを返しますDept

Deptエンティティ リストの最後ではないにもかかわらず、Hibernate をルート エンティティとして認識させる方法はありますか?

注 1:順序を に切り替えようとしました.addJoin("e", "d.empList").addEntity("d", Dept.class)。定義d.empListが必要なため機能しません。Hibernate 内部のどこかでd失敗します ( )。HibernateSystemException : Could not determine fetch ownerorg.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 (私は知っています - レガシー プロジェクト :-) 最新バージョンのソース コードを調べたところ、キー ポイントは変わらないようです)。

4

1 に答える 1