Bonjour,
Voilà mon soucis : je veux faire une association bidirectionnelle plusieurs à plusieurs et quoi que je fasse je tombe sur LazyInitializationException.
J'ai donc les tables USER, ROLE et REL_USER_ROLE(jointure).
J'ai compris que les collections sont chargées de façon "Lazy", c'est à dire à la demande donc il faut une session toujours ouverte quand on veut y accéder. OK.
J'ai également cru comprendre qu'il faut toujours implémenter les fonctions equals/hashCode dans le JavaBean. OK
Voilà des extraits des codes :
User.java
Role.java
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 public class User { ... private Collection<Role> roles = new HashSet<Role>(); public int hashCode() { Iterator iRole = getRoles().iterator(); //ligne 65 while(iRole.hasNext()) { result += 17 * (iRole.next() != null ? iRole.next().hashCode() : 1); } } ... }
User.hbm.xml
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 public class Role { ... private Collection<User> users = new HashSet<User>(); public int hashCode() { Iterator iUser = getUsers().iterator(); //ligne 41 while(iUser.hasNext()) { result += 17 * (iUser.next() != null ? iUser.next().hashCode() : 1); } } ... }
Role.hbm.xml
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 <hibernate-mapping> <class table="USER" name="test.User"> <id access="property" name="id"> <generator class="native"/> </id> ... <set table="REL_USER_ROLE" cascade="all" name="roles"> <key column="user_id" not-null="true"/> <many-to-many column="role_id" class="test.Role"/> </set> ... </class> </hibernate-mapping>
Corps de la fonction de test (obtenir la liste des roles) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 <hibernate-mapping> <class table="ROLE" name="test.Role"> <id access="property" name="id"> <generator class="native"/> </id> ... <set table="REL_USER_ROLE" inverse="true" cascade="all" name="users"> <key column="role_id" not-null="true"/> <many-to-many column="user_id" class="test.User"/> </set> </class> </hibernate-mapping>
Et le message d'erreur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 tx = session.beginTransaction(); Query q = session.createQuery( "from ROLE aRole left join fetch aRole.users" ); resultset = q.list(); tx.commit();
En fait on dirait que ça tourne en rond : quand je veux la liste des roles, hashCode va chercher les users de chaque role, et pour chaque user hibernate va chercher ces roles ...etc
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 May 5, 2010 9:38:18 AM org.hibernate.LazyInitializationException <init> SEVERE: illegal access to loading collection org.hibernate.LazyInitializationException: illegal access to loading collection at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:341) at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86) at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163) at test.Role.hashCode(Role.java:41) at java.util.HashMap.put(HashMap.java:372) at java.util.HashSet.add(HashSet.java:200) at java.util.AbstractCollection.addAll(AbstractCollection.java:305) at org.hibernate.collection.PersistentSet.endRead(PersistentSet.java:329) at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:237) at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:222) at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:195) at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:877) at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:865) at org.hibernate.loader.Loader.doQuery(Loader.java:729) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236) at org.hibernate.loader.Loader.loadCollection(Loader.java:1994) at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36) at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565) at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60) at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716) at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344) at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86) at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163) at test.User.hashCode(User.java:65) at java.util.HashMap.put(HashMap.java:372) at java.util.HashSet.add(HashSet.java:200) at java.util.AbstractCollection.addAll(AbstractCollection.java:305) at org.hibernate.collection.PersistentSet.endRead(PersistentSet.java:329) at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:237) at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:222) at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:195) at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:877) at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:865) at org.hibernate.loader.Loader.doQuery(Loader.java:729) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236) at org.hibernate.loader.Loader.doList(Loader.java:2220) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104) at org.hibernate.loader.Loader.list(Loader.java:2099) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378) at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338) at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172) at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121) at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79) at test.USER_ManagementTest.getAllRoles(USER_ManagementTest.java:71) at test.USER_ManagementTest.main(USER_ManagementTest.java:209)
Je n'ai trouvé sur le net aucun exemple complet de relation many-to-many.
Voyez-vous le problème ? Que me conseillez-vous?
Partager