web-dev-qa-db-ja.com

Criteria.DISTINCT_ROOT_ENTITY vs Projections.distinct

私はHibernateを初めて使用します。次の2つの異なる方法を使用すると、明確な結果が得られることがわかりました。それらの違いは何ですか?いつ他のものを使用するのですか?

Projections.distinct(Projections.property("id"));

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
39
user3123690

名前は似ていますが、使用方法は異なります。

I. Projections.distinct(Projections.property("id"));

このステートメントはSQLステートメントに変換されます。 DBエンジンに渡され、SQL DISTINCTとして実行されます。見る:

例えばこの例:

_List results = session.createCriteria(Cat.class)
    .setProjection( Projections.projectionList()
        .add( Projections.distinct(Projections.property("id")) )
    )
    .list();
_

次のようになります:

_SELECT DISTINCT(cat_id) FROM cat_table
_

II。 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

このステートメントは実行されますex-post。 DBエンジンからSQLクエリが返され、Hibernateが結果セットを繰り返して、エンティティのリストに変換します。

しかし、常に必要ですか?いいえ、ほとんどこれは必要ありません。

クエリに関連付けがある場合、それを使用しなければならない唯一のケース-_one-to-many_ endの結合。

1つcatとその2つkittens、これはtwo行を返しますが、catのみです1つ:

_SELECT cat.*, kitten.*
FROM cat_table as cat 
  INNER JOIN kitten_table kitten ON kitten.cat_id = cat.cat_id
_

したがって、criteriaQueryの最後のステートメント:

_... // criteriaQuery joining root and some one-to-many
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
_

1つの猫のみのリストが作成されます。

80
Radim Köhler

ドキュメントから:DISTINCT_ROOT_ENTITY結果の各行は、ルートエンティティの個別のインスタンスです。

distinct()はプロパティごとにdistinctを選択します。この場合、識別子ごとに

3
birya