web-dev-qa-db-fra.com

Critères.DISTINCT_ROOT_ENTITY vs Projections.distinct

Je suis assez nouveau pour Hibernate. J'ai découvert que nous pouvons obtenir un résultat distinct en utilisant deux méthodes différentes. Quelqu'un pourrait-il me dire quelle est la différence entre eux? Quand utiliser l'un sur l'autre?

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

contre

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
39
user3123690

Bien que des noms similaires, l'utilisation est différente.

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

cette instruction serait traduite en instruction SQL. Il sera transmis au moteur de base de données et exécuté en tant que SQL DISTINCT. Voir:

donc par exemple cet exemple:

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

serait comme:

SELECT DISTINCT(cat_id) FROM cat_table

II. criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

Cette instruction est exécutée ex-post . Une fois que la requête SQL du moteur de base de données est renvoyée et qu'Hibernate itère le jeu de résultats pour le convertir en liste de nos entités.

Mais faut-il toujours? NON, la plupart du temps ce n'est pas nécessaire.

Le seul cas, quand on DOIT l’utiliser, s’il existe une association dans la requête - JOINING the one-to-many End.

Parce que si nous en avons un cat et ses deux kittens, ceci renverrait deux lignes, alors que cat est seulement un:

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

Donc, la déclaration à la fin du criteriaQuery:

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

aboutirait à une liste avec un seul chat.

80
Radim Köhler

From docs: DISTINCT_ROOT_ENTITY Chaque ligne de résultats est une instance distincte de l'entité racine.

distinct () sélectionne distinct par propriété, dans le cas par identifiant

3
birya