Pregunta

Tengo dos tablas, 'jugadores' y 'elementos'. Los jugadores tienen una lista de elementos. Quiero recuperar a los jugadores y todos sus elementos, usando la paginación. Quiero paginar según los jugadores y sin tener en cuenta cuántos elementos hay.

Así que hago algo como esto:

Criteria c = session.createCriteria(Players.class).setFetchMode("items", FetchMode.JOIN);
c.addOrder(Order.asc("playerID"));
c.setFirstResult(0);
c.setMaxResults(25);
List<Player> players = c.list();

¿Esto me dará los primeros 25 jugadores, o me dará los primeros 25 elementos (agrupados por los jugadores)? Me pregunto si este comportamiento no está definido como para las consultas de JPA, o si tal vez hay una respuesta garantizada.

De todos modos, ¿cuáles son las consultas de criterios que me darían los primeros 25 jugadores o las primeras 25 combinaciones de jugadores (ordenadas por ID de jugador, luego ID de elemento)?

¿Fue útil?

Solución

Bastante seguro, pero no al 100%, hará lo siguiente:

Se unirá a los jugadores y a los elementos, ordene a PlayerId y tomará los primeros 25 resultados, todos en una consulta SQL. A partir de estos datos, crea los jugadores y elementos, lo que dará como resultado una cantidad arbitraria de jugadores (menos o igual que 25) con un total de 25 elementos. Puede suceder que el último jugador no obtenga todos los elementos.

Para obtener 25 jugadores, evite FetchMode.JOIN (Para evitar el problema N+1, use el tamaño de lotes en el archivo de asignación):

List<Player> first25Players = session
  .createCriteria(Players.class)
  .addOrder(Order.asc("playerID"))
  .setMaxResults(25)
  .list();

Para obtener 25 elementos, comience la consulta por artículo, no al jugador.

List<Item> first25Items = session
  .createCriteria(Item.class)
  .addOrder(Order.asc("player")) // assuming that player is available
  .setMaxResults(25)
  .list();

Si no hay navegación desde el elemento al reproductor, puede agregar una.

Otros consejos

De las preguntas frecuentes de "Problemas avanzados" para Hibernate:

http://community.jboss.org/wiki/HibernateFaq-AdvancedProblems

También debe ser obvio por qué las operaciones de "límite" basadas en la fila de resultados, como SetFirStresult (5) y SetMaxResults (10) no funcionan con este tipo de consultas de búsqueda ansiosas. Si limita el conjunto de resultados a un cierto número de filas, corta los datos al azar. Un día, Hibernate podría ser lo suficientemente inteligente como para saber que si llama a SetFirStresult () o setMaxResults (), no debería usar una unión, sino una segunda selección SQL. Pruébelo, su versión de Hibernate ya puede ser lo suficientemente inteligente. Si no, escriba dos consultas, una para limitar cosas, la otra para obtener ansioso.

En otras palabras, Hibernate no admite esto. Si fuera más inteligente y supiera cómo se implementó Hibernate, debería haber sido obvio que SetFirStresult y SetMaxResults no hace nada remotamente como la paginación en todos los casos. Era tan obvio que no necesita documentación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top