LazyInitializationException

Salut,
Je me heurte a un probleme incompréhensible de LazyInitializationException.
Dans un service, j'utilise des DAOs. Ce service fait en principe partie d'une transaction (définie avec Spring) :

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
 
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
 
	<bean id="transactionInterceptor"
		class="org.springframework.transaction.interceptor.TransactionInterceptor">
		<property name="transactionManager" ref="transactionManager" />
		<property name="transactionAttributes">
			<props>
				<prop key="*">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>
 
	<bean id="autoProxyCreator"
		class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="interceptorNames">
			<list>
				<idref local="transactionInterceptor" />
			</list>
		</property>
		<property name="beanNames">
			<list>
				<idref local="MyService" />
			</list>
		</property>
	</bean>
En principe, je suis donc bien dans une transaction pour chaque méthode de MyService.
Dans ce service, je fais une opération de ce type :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
Set<Childs> childs = father.getChilds();
Childs firstChild = (Childs)child.toArray()[0];
Le father a déjà été initialisé plus tot et manipulé dans un objet métier. Je suis repassé par mon service pour faire l'appel a getChilds afin d'éviter un probleme de LazyInstantiation car mon association est en lazy loading.

En tests unitaires avec Spring et derby, ca fonctionne.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
    public void testGetChildByIndexForFather ()
    {
        // chaque manipulation bdd est faite dans le service qui doit participer a un transaction
        Father father = __myService.getFatherById(1);
        // Le load est fait dans le service pour éviter la LazyInitializationException
        Childs firstChild = __myService.getChildByIndexForFather(father,0);
        assertNotNull(firstChild );
    }
Par contre dans un cas réel (avec les vrais noms des classes) :

SEVERE failed to lazily initialize a collection of role: net.sf.l2j.gameserver.model.forum.Topic.postses, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: net.sf.l2j.gameserver.model.forum.Topic.postses, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.toArray(PersistentSet.java:171)
at net.sf.l2j.gameserver.services.forum.ForumService.getPostByIndexForTopic(ForumService.java:291)
at net.sf.l2j.gameserver.services.forum.ForumService$$FastClassByCGLIB$$527cee2c.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:675)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:154)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:616)
at net.sf.l2j.gameserver.services.forum.ForumService$$EnhancerByCGLIB$$81b0fdf5.getPostByIndexForTopic(<generated>)
at net.sf.l2j.gameserver.communitybbs.Manager.PostBBSManager.ShowMemoPost(PostBBSManager.java:220)
at net.sf.l2j.gameserver.communitybbs.Manager.PostBBSManager.showPost(PostBBSManager.java:149)
at net.sf.l2j.gameserver.communitybbs.Manager.PostBBSManager.parsecmd(PostBBSManager.java:89)
at net.sf.l2j.gameserver.communitybbs.CommunityBoard.handleCommands(CommunityBoard.java:71)
at net.sf.l2j.gameserver.clientpackets.RequestBypassToServer.runImpl(RequestBypassToServer.java:220)
at net.sf.l2j.gameserver.clientpackets.ClientBasePacket.run(ClientBasePacket.java:81)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Pourtant dans ForumService je dois avoir ouvert une transaction et ma session ne doit pas être close.
Qu'est ce que j'ai loupé ?