Respuestas:
Aquí hay un fragmento de hql que usamos. (Los nombres se han cambiado para proteger las identidades)
String queryString = "select distinct f from Foo f inner join foo.bars as b" +
" where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});
Vale la pena señalar que la distinctpalabra clave en HQL no se asigna directamente a la distinctpalabra clave en SQL.
Si usa la distinctpalabra clave en HQL, a veces Hibernate usará la distinctpalabra clave SQL, pero en algunas situaciones usará un transformador de resultados para producir resultados distintos. Por ejemplo, cuando está utilizando una combinación externa como esta:
select distinct o from Order o left join fetch o.lineItems
En este caso, no es posible filtrar duplicados a nivel SQL, por lo que Hibernate usa ResultTransformerpara filtrar duplicados después de que se haya realizado la consulta SQL.
haz algo como esto la próxima vez
Criteria crit = (Criteria) session.
createCriteria(SomeClass.class).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List claz = crit.list();
También puedes usar Criteria.DISTINCT_ROOT_ENTITY con la consulta de Hibernate HQL.
Ejemplo:
Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
Tuve algunos problemas con los transformadores de resultados combinados con consultas HQL. Cuando lo intenté
final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);
no funcionó. Tuve que transformar manualmente así:
final List found = trans.transformList(qry.list());
Con Criteria API, los transformadores funcionaron bien.
Mi consulta principal se veía así en el modelo:
@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd",
query = "select distinct i from CentralFinancialAgencyAccountCd i")
Y todavía no obtenía lo que consideraba resultados "distintos". Eran simplemente distintos basados en una combinación de teclas primarias sobre la mesa.
Entonces DaoImpl, agregué un cambio de una línea y terminé obteniendo el retorno "distinto" que quería. Un ejemplo sería en lugar de ver 00 cuatro veces, ahora solo lo veo una vez. Aquí está el código que agregué a DaoImpl:
@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {
Session session = (Session) entityManager.getDelegate();
org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
List<CacheModelBase> codes;
codes = q.list();
return codes;
}
¡Espero que esto haya ayudado! Una vez más, esto solo podría funcionar si sigue prácticas de codificación que implementan el tipo de proyecto de servicio, dao y modelo.
Suponga que tiene una entidad de cliente asignada a la tabla CUSTOMER_INFORMATION y desea obtener una lista de nombres distintos de cliente. Puede usar el siguiente fragmento para obtener lo mismo.
Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();
Espero que ayude. Entonces aquí estamos usando group by en lugar de usar una palabra clave distinta.
También anteriormente me resultó difícil usar una palabra clave distinta cuando quiero aplicarla a varias columnas. Por ejemplo, quiero obtener una lista de nombre distinto, apellido y luego agrupar por simplemente funcionaría. Tuve dificultades para usar distinto en este caso.
Tengo una respuesta para que Hibernate Query Language use campos distintos. Puede usar * SELECT DISTINCT (TO_CITY) FROM FLIGHT_ROUTE *. Si usa una consulta SQL , devuelve String List. No puede usar su valor de retorno por clase de entidad. Entonces, la respuesta para resolver ese tipo de problema es usar HQL con SQL .
FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);
De la declaración de consulta SQL obtuvo DISTINCT ROUTE_ID y la entrada como una lista. Y la consulta IN filtra el TO_CITY distinto de IN (Lista).
El tipo de retorno es el tipo Entity Bean. Entonces puede hacerlo en AJAX como AutoComplement .
Que todo esté bien
Puede utilizar la palabra clave distinta en su generador de criterios como este.
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));
Y crea el constructor de campo en tu clase de modelo.
Si necesita usar una nueva palabra clave para un DTO personalizado en su declaración de selección y necesita elementos distintos , use nuevo fuera de nuevo como sigue:
select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...