¿Cómo se crea una consulta distinta en HQL
Pregunta
¿Hay alguna manera de crear una consulta distinta en HQL? Ya sea usando el "distintivo" palabra clave o algún otro método. No estoy seguro de si distintivo es un trabajo de clave válido para HQL, pero estoy buscando el equivalente HQL de la palabra clave SQL "distintivo".
Solución
Aquí hay un fragmento de hql que usamos. (Se han cambiado los nombres 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});
Otros consejos
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 distinct
SQL, 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 a nivel de SQL en este caso, por lo que Hibernate utiliza un ResultTransformer
para 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 puede usar Criteria.DISTINCT_ROOT_ENTITY
con la consulta Hibernate HQL 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 las consultas HQL. Cuando lo intenté
final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);
no funcionó. Tuve que transformarme manualmente de esta manera:
final List found = trans.transformList(qry.list());
Con Criteria, los transformadores API 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 "distinto" resultados. Simplemente eran distintos en función de una combinación de teclas primarias en la tabla.
Entonces, en el DaoImpl
agregué un cambio de una línea y terminé obteniendo el " distinto " Regreso 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é al 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 podría funcionar solo si sigue prácticas de codificación que implementan el servicio, el dao y el tipo de proyecto modelo.
Suponga que tiene una entidad de cliente asignada a la tabla CUSTOMER_INFORMATION y desea obtener una lista de firstName distintos de cliente. Puede usar el fragmento a continuación 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. Así que aquí estamos usando group by en lugar de usar palabras clave distintas.
También anteriormente me resultaba difícil usar palabras clave distintas cuando quiero aplicarlo a varias columnas. Por ejemplo, quiero obtener una lista de primer nombre distinto, apellido y luego agrupar por simplemente funcionaría. Tuve dificultades para usar distinto en este caso.
Puede usted 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.
Tengo una respuesta para Hibernate Query Language para usar campos distintos. Puede usar * SELECT DISTINCT (TO_CITY) FROM FLIGHT_ROUTE *. Si utiliza la consulta SQL , devuelve la Lista de cadenas. No puede usar el 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 e ingresó como una Lista. Y la consulta IN filtra el distintivo TO_CITY de IN (Lista).
El tipo de retorno es de tipo Entity Bean. Por lo tanto, puede hacerlo en AJAX, como Autocomplement .
Puede que todo esté bien