Je suis nouveau en JPA et je veux mettre en œuvre un JPA DAO générique et devez trouver le nombre de lignes d'un résultat de la requête défini pour mettre en œuvre la pagination. Après avoir cherché sur le Web, je ne trouve pas de moyen pratique de le faire. Voici le code suggéré dans de nombreux articles: Cependant, ce code ne fonctionne pas lorsque vous utilisez mise à jour:
Voici le code qui crée des critères de critère: p> et certaines jointures peuvent être ajoutées à la racine jusqu'à ce que la requête ait été exécutée: p> joindre code>. Y a-t-il un moyen de compter les lignes d'un ensemble de résultats de requête à l'aide de l'API de critère JPA? P>
public Predicate addPredicate(Root<T> root) {
Predicate predicate = getEntityManager().getCriteriaBuilder().ge(root.join(Entity_.someList).get("id"), 13);
return predicate;
}
3 Réponses :
Je ne peux pas vous dire où votre problème est, mais je peux vous dire que les questions de comptage avec des jointures fonctionnent bien, au moins dans Ce que je fais habituellement est: p> regarder votre pseudo-code, il semble qu'il semble que que vous utilisez la mauvaise classe de la méthode de jointure: elle doit être la classe de départ, pas la classe cible. p> p> Eclipselink Code> JPA. Je suppose que c'est que c'est des trucs standard, il devrait donc fonctionner aussi dans l'hibernate. Je commencerais par simplifier votre code afin d'attraper où le problème est.
Je vois que vous avez copié des morceaux de votre requête de contrôle de votre requête principale. Peut-être que vous pouvez essayer de changer un peu cette approche, juste pour le débogage du but.
Lire votre réponse simple après une bonne nuit, je me suis venu de 10 heures de difficulté avec cette requête et des critères de critère ... :)
J'ai fait ceci:
public Long getRowCount(CriteriaQuery criteriaQuery,CriteriaBuilder criteriaBuilder,Root<?> root){ CriteriaQuery<Long> countCriteria = criteriaBuilder.createQuery(Long.class); Root<?> entityRoot = countCriteria.from(root.getJavaType()); entityRoot.alias(root.getAlias()); doJoins(root.getJoins(),entityRoot); countCriteria.select(criteriaBuilder.count(entityRoot)); countCriteria.where(criteriaQuery.getRestriction()); return this.entityManager.createQuery(countCriteria).getSingleResult(); } private void doJoins(Set<? extends Join<?, ?>> joins,Root<?> root_){ for(Join<?,?> join: joins){ Join<?,?> joined = root_.join(join.getAttribute().getName(),join.getJoinType()); doJoins(join.getJoins(), joined); } } private void doJoins(Set<? extends Join<?, ?>> joins,Join<?,?> root_){ for(Join<?,?> join: joins){ Join<?,?> joined = root_.join(join.getAttribute().getName(),join.getJoinType()); doJoins(join.getJoins(),joined); } }
@ lubo08 a donné une réponse correcte - félicitations pour lui strong>.
Mais pour deux cas de coin, son code ne fonctionnera pas: Ainsi, pour l'exhaustivité, j'ai osé améliorer sa solution et présenter ci-dessous: P> Bien que ce soit toujours
comptage code> nécessitent également ces alias. li>
root.fetch (..) code> au lieu de
root.join (..) code>] li>
ul>
Mais j'espère que cela aide quelqu'un. p> p>
Je devais ajouter un prédicat cb.equal (campagne, racine) code>, sinon il y a une "jointure de cartésien"
Pouvez-vous nous montrer comment avez-vous défini des critères de critère > Critères
Découvrez d'autres réponses à des problèmes similaires: Stackoverflow.com/questions/9001289/... et Stackoverflow.com/questions/9025196/...
@Perissf tnx 4 votre attention. Je vérifie ceux-ci, mais je n'ai pas m'aidé. Je ne sais pas comment obtenir des comptes de ligne lors de l'utilisation de la jointure dans ma requête de critère JPA.
Vous n'avez toujours pas montré tout votre code. Comment générez-vous les prédicats pour la déclaration suivante? Les jointures devraient produire des prédicats pour le lieu où. Quelle erreur obtenez vous?
@Perissf i Ajouter plus de détails au message principal.
Laissez-nous Continuer cette discussion en chat
@PERISSF: J'ai un problème similaire, la question clé ici est que vous pouvez obtenir des prédicats d'un critère de critère (à l'aide du prédicat OldPredicate = Critères.GetRestriction ()) mais vous ne pouvez pas les définir dans une autre requête puisqu'elle est liée au premier critère Objet root. Ou plutôt que vous pouvez appeler Newcriteriaquery.where (Oldpredicate); Mais lorsque vous essayez de l'exécuter, vous recevez QuerySyntaxException comme décrit dans Post
@regis: Veuillez poser une nouvelle question avec tous les détails nécessaires. Quoi qu'il en soit, je pense que ce n'est jamais une bonne idée de réutiliser des prédicats écrits pour une autre requête que vous décrivez
@Perissf: La fonctionnalité que je cherchais est un équivalent des critères détachés d'Hibernate. Malheureusement, on dirait qu'il n'y a pas d'option de telle en JPA 2.0: Stackoverflow.com/questions/3636457/JPA-2 -Remote-critères