¿Cómo se crea una consulta Distinct en HQL?

¿Hay alguna manera de crear una consulta Distinct en HQL? Ya sea usando la palabra clave “distinta” o algún otro método. No estoy seguro de si es distinta una clave válida para HQL, pero estoy buscando el equivalente HQL de la palabra clave SQL “distinto“.

Aquí hay un fragmento de hql que usamos. (Los nombres han sido cambiados 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 palabra clave distinct en HQL no se asigna directamente a la palabra clave distinct en SQL.

Si usa la palabra clave distinct en HQL, a veces Hibernate usará la palabra clave SQL distinct , pero en algunas situaciones usará un transformador de resultados para producir resultados distintos. Por ejemplo, cuando usa una combinación externa como esta:

 select distinct o from Order o left join fetch o.lineItems 

No es posible filtrar duplicados en el nivel de SQL en este caso, por lo que Hibernate usa un ResultTransformer para filtrar duplicados después de que se haya realizado la consulta SQL.

hacer 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 puede usar Criteria.DISTINCT_ROOT_ENTITY con Hibernate HQL query también.

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 transformarme manualmente así:

 final List found = trans.transformList(qry.list()); 

Con los transformadores API de Criteria funcionó 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 los resultados que consideraba “distintos”. Eran simplemente distintos en función de una combinación de teclas principal en la mesa.

Entonces en el 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 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 codes; codes = q.list(); return codes; } 

Espero que esto haya ayudado! Una vez más, esto solo podría funcionar si está siguiendo las prácticas de encoding que implementan el servicio, el dao y el tipo de modelo de proyecto.

Supongamos que tiene una entidad de cliente asignada a la tabla CUSTOMER_INFORMATION y desea obtener una lista de primer nombre distinto de cliente. Puedes usar el siguiente fragmento para obtener el 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 palabras clave distintas.

También anteriormente me resultaba difícil usar palabras clave distintas cuando quería aplicarlo a varias columnas. Por ejemplo, quiero obtener una lista de FirstName distinto, lastName then group by simplemente funcionaría. Tuve dificultades para usar distinct en este caso.

Tengo una respuesta para Hibernate Query Language para usar campos Distinct. Puede usar * SELECT DISTINCT (TO_CITY) FROM FLIGHT_ROUTE *. Si usa una consulta SQL , devuelve la lista de cadenas. No puede usarlo para devolver el valor 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 statement de consulta SQL obtuvo DISTINCT ROUTE_ID e ingresó como una lista. Y la consulta IN filtra el distinto TO_CITY de IN (Lista).

El tipo de devolución es del tipo Entity Bean. Entonces puedes hacerlo en AJAX como AutoComplement .

Que todo esté bien

Puede usted la palabra clave distinta en su creador de criterios como este.

 CriteriaBuilder builder = session.getCriteriaBuilder(); CriteriaQuery query = builder.createQuery(Orders.class); Root 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.