org.mise en veille prolongée.hql.ast.QueryTranslatorImpl liste à l'ATTENTION de: firstResult/maxResults spécifié à la collecte de l'extraction; l'application dans la mémoire
Je suis face à un problème, j'ai une requête en JPA. comme je l'ai certaines collections-je besoin pour utiliser left join fetch ou inner join fetch
Mon problème est dans l'utilisation de la setFirstResult
et setMaxResult
afin de ramener un nombre précis de résultat. chaque fois que je vois le résultat complet est ramener ET qu'APRÈS la maxResult est utilisé.
Est-il possible de faire la maxResult avant ?
Merci beaucoup !
ici, il est plus d'informations :
mon problème est que lorsque j'utilise :
startIndex = 0;
maxResults = 10;
query.setFirstResult(startIndex);
query.setMaxResults(maxResults);
Je vois ce message dans mon journal :
7 juin 2011 09:52:37 org.mise en veille prolongée.hql.ast.QueryTranslatorImpl liste
ATTENTION: firstResult/maxResults spécifié à la collecte de l'extraction;
l'application en mémoire!
Je vois le résultat 200 revenir (en log) et après dans le HashSet, j'ai enfin le 10 le résultat que je demande.
sa semble en mémoire est de ramener le résultat 200 et après la maxResults est appliquée dans la mémoire.
Je suis à la recherche s'il existe une façon d'être en mesure de récupérer et de limiter le nombre de résultat.
J'ai utilisé une solution de contournement, je fais une première requête pour demander l'id de ma commande , sans chercher, utilisé le maxResult.
tout fonctionne parfaitement, il est utilisé à la limite de l'instruction.
Après je utiliser mon "grand" de la requête avec le récupérer et de limiter le nombre de résultats à l'intérieur de la liste des id de ramener dans le premier.
ici c'est ma requête complète sans ma solution (notez qu'il n'y a pas de limite généré parler que par @Bozho ):
select o from Order o
left join fetch o.notes note
left join fetch o.orderedBy orderedBy
left join fetch orderedBy.address addressOrdered
left join fetch orderedBy.language orderedByLg
left join fetch orderedByLg.translations orderedByLgTtrad
left join fetch o.deliveredTo deliveredTo
left join fetch deliveredTo.address addressDelivered
left join fetch deliveredTo.language deliveredToLg
left join fetch deliveredToLg.translations
left join fetch o.finalReceiptPlace finalReceiptPlace
left join fetch finalReceiptPlace.address addressFinalReceiptPlace
left join fetch finalReceiptPlace.language finalReceiptPlaceLg
left join fetch finalReceiptPlaceLg.translations
inner join fetch o.deliveryRoute delivery
left join fetch delivery.translations
inner join fetch o.type orderType
left join fetch orderType.translations
inner join fetch o.currency currency
left join fetch currency.translations
left join fetch o.attachments
left join fetch note.origin orig
left join fetch orig.translations
left join fetch o.supplier sup
left join fetch sup.department dep
left join fetch o.stateDetail stateD
inner join fetch stateD.state stat
where 1=1 and o.entryDate >= :startDat
Il peut être intéressant de savoir, ce que le SGBD sous-jacent. Oracle?
Pour info, j'ai résolu ce problème pour mes fins en se divisant en 2 requêtes... La première requête serait de générer une liste d'Id qui je serais alors en utilisant dans la seconde requête pour sélectionner les articles que j'avais besoin de Récupérer des relations.... Par exemple, j'ai choisi le Id pour la Vente de l'entité avec mon setMaxResults(int) et setFirstResult(int) et JUSTE récupéré une liste de valeurs Longues. J'ai ensuite utilisé ces valeurs comme partie de la/dans la partie de la deuxième requête et SEULEMENT utilisé le Chercher dans les relations que la deuxième requête.
Thx Deven. Votre solutuion sonne bien!
OriginalL'auteur Yannick Eurin | 2011-06-06
Vous devez vous connecter pour publier un commentaire.
De comprendre pourquoi Hibernate pour cela, vous devez comprendre comment Hibernate ne l'ORM (Object-Relational Mapping) impliqués pour des Entités JPA.
Envisager une simplification de la configuration des Entités de votre commande. Classe
Order
contient 2 champs:number
etcustomerId
et une liste des lignes de commande. ClasseOrderLine
contientproductCode
etquantity
champs, ainsi que d'unuid
clé et une référence à la société mère de l'Ordre.Ces classes peuvent être définies ainsi:
Maintenant, si vous avez effectué la suite de la requête JPQL sur ces Entités:
puis Hibernate effectue cette requête comme une "aplaties" requête SQL similaire à la suivante:
qui donnerait un résultat de ce genre:
qui Hibernate serait l'utilisation de 'reconstruire'
Order
objets connectés à des listes deOrderLine
des sous-objets.Cependant, puisque le nombre de lignes de commandes par ordre est aléatoire, il n'existe aucun moyen pour Hibernate pour connaître le nombre de lignes de cette requête à prendre pour obtenir le nombre maximal spécifié de
Order
les objets requis. Donc, il doit prendre la totalité de la requête et de construire les objets en mémoire jusqu'à ce qu'il a le droit montant, avant de jeter le reste de l'ensemble de résultats. Le journal avertissement ce produit fait allusion à ceci:Nous sommes seulement en train de découvrir maintenant que ces requêtes peuvent avoir un impact significatif sur le serveur de l'utilisation de la mémoire, et nous avons eu des problèmes avec notre serveur de tomber avec des erreurs de mémoire insuffisante lors de ces requêtes sont tentées.
Par le chemin, je vais dire maintenant que c'est principalement de la théorie de ma part et je n'ai aucune idée de comment le réel Hibernate code fonctionne. La plupart de ce que vous pouvez glaner dans les journaux lorsque vous avez Hibernate journalisation des requêtes SQL qu'il génère.
Mise à JOUR:
Récemment, j'ai découvert un peu "chasse aux sorcières" avec la ci-dessus.
Envisager une troisième Entité appelée
Shipment
qui est pour une ou plusieurs Lignes de Commande.La
Shipment
entité aurait un@ManyToOne
association pour laOrder
entité.Disons que vous avez 2 Envois pour la même Commande qui dispose de 4 Lignes.
Si vous effectuez une requête JPQL pour les éléments suivants:
Vous attendent (ou au moins je l'ai fait) pour obtenir 2 de l'envoi des objets de dos, chacun avec une référence au même objet de Commande, qui lui-même contient les 4 Lignes.
Nope, de nouveau mal! En fait, vous obtenez 2 Envoi d'objets, chacun se référant à la même Ordre d'objet, qui contient 8 Lignes! Oui, les Lignes se dupliqué dans l'Ordre! Et oui, c'est à dire même si vous spécifiez la clause DISTINCT.
Si vous cette question de la recherche ici ou ailleurs (et notamment la veille prolongée forums), vous verrez que c'est en fait un fonction pas un bug, selon les Hibernate pouvoirs en place. Certaines personnes effectivement voulez ce comportement!
Allez comprendre.
OriginalL'auteur DuncanKinnear
Cela dépend du moteur de base de données utilisé...
J'ai le même problème avec Derby DB
setFirstResult
/setMaxResults
ne sont pas utilisés.ROW_NUMBER() OVER()...
semble être la solution.Unfortunally je ne trouve pas comment je peux générer de telles demandes avec JPA sans spécifing la totalité de la requête en SQL.
OriginalL'auteur SR_
setMaxResult(10) encapsule la requête avec une autre limitation de résultat, par exemple pour oracle:
select * from ("votre requête ici") where rownum<10
J'ai trouvé que c'aujourd'hui lors de l'enquête de la requête qui a eu 64 secondes, maintenant, il faut 1 seconde.
...la même chose pour les critères.setProjection(Projections.rowCount()).setMaxResults(10)
OriginalL'auteur nigi