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.