projections ordenar example ejemplo hibernate criteria having

example - ordenar criteria hibernate



Hibernate Criteria API-cláusula HAVING de la solución de problemas (3)

He escrito una consulta usando la API de Hibernate Criteria para obtener una suma de un valor particular, ahora necesito poder restringir el resultado a las filas donde esa suma es mayor o igual a un valor particular.

Normalmente usaría una cláusula HAVING en mi SQL para hacer esto, pero la API de Criteria no parece respaldar eso en este momento.

En SQL sin procesar, esto es lo que necesito que haga:

SELECT user_pk, sum(amount) as amountSum FROM transaction GROUP BY user_pk HAVING amountSum >=50;

Una solución alternativa que pensé es usar una subconsulta en la cláusula FROM que toma este valor de suma y usar una consulta externa para restringirlo usando una cláusula WHERE.

Por lo tanto, en SQL crudo se verá algo así como:

SELECT user_pk, amountSum FROM (SELECT user_pk, sum(amount) as amountSum FROM transaction GROUP BY user_pk) WHERE amountSum > 50;

¿Alguien puede señalarme en la dirección correcta cómo puedo escribir esto usando Criteria API, o cualquier otra sugerencia / solución alternativa que pueda usar para resolver el problema HAVING?

Este es el código API de Criteria que tengo para el ejemplo anterior

DetachedCriteria criteria = DetachedCriteria.forClass(Transaction.class,"transaction"); criteria.setProjection(criteria.setProjection(Projections.projectionList().add( Projections.groupProperty("user.userPK").as("user_pk")).add( Projections.sum("transaction.amount").as("amountSum")));

¡Gracias!


No sé de qué manera Hibernate / NHibernate pueda usar una subconsulta en la cláusula FROM, pero puede usarlos en la cláusula WHERE. Disculpas por los errores de código de Java / Hibernate, estoy más familiarizado con C # / NHibernate.

DetachedCriteria subQuery = DetachedCriteria.forClass(Transaction.class); subQuery.setProjection(Projections.sum("amount")); subQuery.add(Expression.eqProperty("userPk", "tOuter.userPk")); DetachedCriteria outerQuery = DetachedCriteria.forClass(Transaction.class, "tOuter"); outerQuery.setProjection(Projections.projectionList() .Add(Projections.sum("amount").as("sumAmount")) .Add(Projections.groupProperty("userPk").as("user_pk")); outerQuery.add(Subqueries.le(50, subQuery));

Este código debería dar como resultado SQL similar a:

SELECT tOuter.userPk as user_pk, sum(tOuter.amount) as sumAmount FROM transaction tOuter WHERE 50 <= (SELECT sum(amount) FROM transaction WHERE userPk = tOuter.userPk) GROUP BY tOuter.userPk

La desventaja de este enfoque es que calcula cada una de las sumas dos veces, esto podría tener un efecto perjudicial en el rendimiento dependiendo de la cantidad de datos involucrados; en ese caso, querrá usar una consulta HQL que admita la cláusula HAVING.



HHH-1700 se marcó como duplicado de HHH-1043 y, por lo tanto, no se solucionará. Encontrará mi solución y mi solución, así como la de otras personas, en HHH-1043 .