2010-12-01 4 views
2

Compte tenu de la situation suivante dans une application Web:Pourquoi EntityManager.merge() empêche LazyInitializationException alors que EntityManager.find() non?

// EntityManager em, one per Request with Spring's OpenEntityManagerInViewFilter 
// Parent oldParent, from previous request (and therefore another persistence context) 
Parent parent = em.find(Parent.class, oldParent.getId()); 
List<Child> children = parent.getChildren(); // Mapped collection with LazyLoading 
for (Child child : children) { 
    ... 

L'appel de la liste iterator provoque une LazyInitializationException. Ceci est déroutant, car la récupération de la liste des enfants se produit dans le même contexte de persistance (ou ai-je tort?). Mais, en utilisant merge(), cela fonctionne. Comme si deux requêtes partageaient un contexte de persistance.

Parent parent = em.merge(oldParent); 
List<Child> children = parent.getChildren(); 
for (Child child : children) { 
    ... 
// No Exception!! 

Quelle est mon erreur de raisonnement?

Addition
J'ai prouvé que l'erreur ne provient pas parent.getId(). Cela fait partie de la piletrace:

at org.hibernate.collection.PersistentList.iterator(PersistentList.java:138) 

Cela signifie que c'est réellement l'itérateur qui cause le problème. Et ça devient encore plus bizarre - J'ai vérifié que dans le premier cas (avec find()), une instruction select est émise par hibernate pour récupérer un nouvel objet de la base de données, pas du cache du contexte de persistance.

Addition2
est ici un peu plus stacktrace:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: edeka.sw.phb.model.Chapter.subChapters, no session or session was closed 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380) 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372) 
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365) 
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108) 
    at org.hibernate.collection.PersistentList.iterator(PersistentList.java:138) 
    at java.util.Collections$UnmodifiableCollection$1.<init>(Collections.java:1022) 
    at java.util.Collections$UnmodifiableCollection.iterator(Collections.java:1021) 
    //... followed by the line of the foreach. 

Répondre

0

Je pense que votre problème n'est pas dans la partie itérer parce que vous itérer avec le nouveau parent récemment chargé. Le problème doit être avec le .getId() qui semble ne pas être chargé puis la fusion fonctionne parce que ne pas appeler le .getId()

+0

Merci lujop, mais ce n'est pas le cas. Je peux réussir l'obtention de l'ID via 'parent.getId()', mais l'itération échoue. S'il vous plaît voir mes modifications. – Zeemee

+0

C'est très étrange. Pouvez-vous mettre la stacktrace détaillée? Et le code est exactement ce que vous mettez ou vous le simplifiez? – lujop

+0

J'ai ajouté plus de stacktrace. J'ai un peu simplifié le code, mais cela ne devrait pas avoir d'importance. – Zeemee

Questions connexes