projections example addorder hibernate nhibernate distinct hibernate-criteria

example - in criteria in hibernate



Criteria.DISTINCT_ROOT_ENTITY vs Projections.distinct (2)

Soy bastante nuevo para Hibernate. Descubrí que podemos obtener resultados distintos usando dos formas diferentes. ¿Alguien podría decirme cuál es la diferencia entre ellos? ¿Cuándo usar uno sobre otro?

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

vs

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);


From docs: DISTINCT_ROOT_ENTITY Cada fila de resultados es una instancia distinta de la entidad raíz

distinct () selecciona distinct por propiedad, en su caso por identificador


Si bien nombres similares, el uso es diferente.

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

esta declaración se traduciría a la declaración de SQL. Se pasará a DB Engine y se ejecutará como SQL DISTINCT . Ver:

por ejemplo, este ejemplo:

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

Parece que:

SELECT DISTINCT(cat_id) FROM cat_table

II. criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

Esta declaración se ejecuta ex-post . Una vez que se devuelve la consulta SQL del motor de DB, Hibernate itera el conjunto de resultados para convertirlo en una lista de nuestras entidades.

Pero, ¿es necesario siempre? NO, principalmente esto no es necesario.

El único caso, cuando DEBEMOS usar eso, si hay una asociación en la consulta, UNIÉNDOSE al extremo one-to-many .

Porque si tenemos un cat y sus dos kittens , esto devolvería dos filas, mientras que el cat es solo uno:

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

Por lo tanto, la declaración al final de los criteriaQuery :

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

daría como resultado una lista con solo un gato.