Posterior a consultar con especialistas en esta materia, programadores de varias áreas y maestros hemos dado con la solución al problema y la plasmamos en esta publicación.
Solución:
No sé cómo hacer eso con JPQL, pero probablemente pueda manejarlo con Criteria API, al menos estoy bastante seguro de que podemos hacer esto con las subconsultas de criterios de Hibernate, así que supongo que también es posible con JPA incluso si los criterios de JPA api me parece un poco confuso.
Verifique esto: JPA 2.0, API de criterios, subconsultas, en expresiones
De todos modos, ni siquiera necesita un límite en su subconsulta.
Su consulta original: seleccione RangeStart de ipinfo donde RangeStart >= 1537022421 order by RangeStart asc limit 1 Parece que desea el RangeStart mínimo de su lista de ipinfo, que está justo por encima de un valor dado. La función min se ha hecho para eso.
Simplemente podría usar una subconsulta como esta:
select min(RangeStart) from ipinfo where RangeStart >= 1537022421
Incluso si necesita que se devuelva otra ipinfo en su subconsulta, podría hacerse con algo como eso:
select RangeEnd, anything,blabla from ipinfo where RangeStart = (
select min(RangeStart) from ipinfo where RangeStart >= 1537022421
)
No hay puro Solución JPA para esto. Podrías hacer uso de una costumbre funcion SQL que se ejecuta durante el tiempo de generación de consultas SQL. Todos los proveedores de JPA admiten algo así de una forma u otra.
Si no desea implementar eso usted mismo o incluso desea una API adecuada para construir tales consultas, solo puedo recomendarle la biblioteca que implementé llamada Blaze-Persistence.
Aquí está la documentación que muestra el caso de uso de límite/compensación con subconsultas: https://persistence.blazebit.com/documentation/core/manual/en_US/index.html#pagination
Su consulta podría tener este aspecto con la API del generador de consultas:
criteriaBuilderFactory.create(entityManager, IpInfo.class)
.where("rangeEnd").lt()
.from(IpInfo.class, "subInfo")
.select("subInfo.rangeStart")
.where("subInfo.rangeStart").geExpression("1537022421")
.orderByAsc("subInfo.rangeStart")
.setMaxResults(1)
.end()
.where("1537022421").leExpression("rangeEnd")
.orderByDesc("rangeEnd")
.setMaxResults(1)
Esencialmente se reduce a usar el LIMIT
funcion SQL que está registrado por Blaze-Persistence. Entonces, cuando inicia Blaze-Persistence con su EntityManagerFactory, incluso debería poder usarlo así
entityManager.createQuery(
"select * from ipinfo where RangeEnd < LIMIT((" +
" select RangeStart " +
" from ipinfo " +
" where RangeStart >= 1537022421 " +
" order by RangeStart asc" +
"),1) " +
"and (1537022421 <= RangeEnd)" +
"ORDER BY RangeEnd desc"
).setMaxResults(1)
Si está utilizando EclipseLink, la convención de llamada de tales funciones parece OPERATOR('LIMIT', ...)
.
valoraciones y reseñas
Si sostienes alguna vacilación o disposición de perfeccionar nuestro tutorial te proponemos ejecutar un paráfrasis y con deseo lo leeremos.