Question

J'ai deux tables, "Joueurs" et "Objets".Les joueurs ont une liste d'objets.Je veux récupérer les joueurs et tous leurs objets en utilisant la pagination.Je veux paginer en fonction des joueurs et sans tenir compte du nombre d'objets.

Je fais donc quelque chose comme ceci:

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();

Est-ce que cela va me donner les 25 premiers joueurs, ou est-ce que cela me donnera les 25 premiers éléments (regroupés par joueurs)?Je me demande si ce comportement n'est pas défini comme il le serait pour les requêtes JPA, ou s'il existe peut-être une réponse garantie.

Quoi qu'il en soit, quelles sont les requêtes Critères qui me donneraient les 25 premiers joueurs ou les 25 premières combinaisons joueur-élément (classées par ID de joueur, puis par ID d'élément)?

Était-ce utile?

La solution

Bien sûr, mais pas à 100%, il fera ce qui suit:

Il rejoindra les joueurs et les éléments, triés par playerID et prendra les 25 premiers résultats, le tout dans une seule requête SQL.À partir de ces données, il crée les joueurs et les objets, ce qui entraînera un nombre arbitraire de joueurs (inférieur ou égal à 25) avec un total de 25 éléments.Il se peut que le dernier joueur n'obtienne pas tous les objets.

Pour obtenir 25 joueurs, évitez FetchMode.JOIN (pour éviter le problème N + 1, utilisez la taille du lot dans le fichier de mappage):

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

Pour obtenir 25 éléments, lancez la requête par élément et non par lecteur.

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

S'il n'y a pas de navigation entre l'élément et le lecteur, vous pouvez en ajouter un.

Autres conseils

Dans la FAQ «Problèmes avancés» pour Hibernate:

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

Il devrait également être évident pourquoi "limite" basée sur les lignes de l'ensemble de résultats opérations, telles que setFirstResult (5) et setMaxResults (10) ne fonctionnent pas avec ce genre de recherche impatiente requêtes. Si vous limitez le jeu de résultats à un certain nombre de lignes, vous coupez données au hasard. Un jour, Hibernate pourrait soyez assez intelligent pour savoir que si vous appelez setFirstResult () ou setMaxResults () il ne doit pas utiliser de join, mais un second SQL SELECT. Essayez-le, votre version d'Hibernate pourrait être déjà assez intelligent. Sinon, écrivez deux requêtes, une pour limiter les choses, l'autre pour la récupération impatiente.

En d'autres termes, Hibernate ne prend pas en charge cela. Si vous étiez plus intelligent et saviez comment Hibernate a été implémenté, il aurait dû être évident que setFirstResult et setMaxResults ne font rien à distance comme la pagination dans tous les cas. C'était tellement évident qu'il n'a pas besoin d'être documenté.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top