J'utilise la récupération par lots d'hibernate pour améliorer les performances des requêtes. Dans mon persistence.xml j'ai ajouté le paramètre suivant:Mise en veille prolongée: ordre de récupération inattendu pour l'extraction par lots
<property name="hibernate.default_batch_fetch_size" value="50"/>
J'ai une entité A, qui a un 1: n rapport à une entité B. Les données de ce rapport sont extraites paresseusement. Maintenant, j'ai la situation suivante:.
- je charge 10000 entités de type A de DB
- J'itérer sur ces entités et initialisez la relation paresseuse en appelant a.getBs() taille()
- En faisant cela, hibernate n'initialise pas seulement la dépendance de l'entité courante, mais charge en plus la dépendance de 49 entités supplémentaires de la liste. Ce comportement est attendu
Le SQL généré ressemble à ceci:
select
b0_.SOMETHING as SOMETHING1_1_,
...
from
XYZ.B b0_
where
b0_.A_ID in (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ...
)
Mon vrai problème est que veille prolongée ne se charge pas les entités de la liste des résultats dans l'ordre attendu. Lorsque j'accède à la première entrée de la liste, elle ne charge pas les données pour les entités 2-50, mais charge les données pour 49 entrées aléatoires de la liste. (par exemple, il peut initialiser les données des entités 3, 7, 100, 2001, ...). Ce comportement est assez étrange et je me demande comment le changer pour charger les données dans l'ordre attendu.
Problèmes courants liés au comportement décrit.
- Utilisation de la mémoire. Pendant l'itération de la liste, Hibernate initialise beaucoup de données, ce qui sera BEAUCOUP plus tard. En plus de l'algorithme ci-dessus, j'ai ajouté du code, qui supprime les enregistrements traités de la liste et appelle session.evict (entité), pour rendre l'entité éligible pour la récupération de place. Ceci ne fonctionne bien sûr pas maintenant.
- La vitesse de requête est très lente au début de l'itération car Hibernate interroge la base de données pour presque toutes les entités traitées. Cela provoque des problèmes car j'écris les entités dans le flux d'une application Web pour téléchargement lors du traitement. En conséquence, la vitesse de téléchargement est très lente au début et accélère lorsque plus d'entités ont été chargées en mémoire et que moins d'appels db sont requis.
Merci beaucoup pour votre aide et meilleures salutations
Thomas
Utilisez-vous les listes itérateur()? – KarlP
J'ai testé l'itérateur et la nouvelle boucle for (pour (A a: resultlist)) – Thomas