Bonjour,
J'utilise Hibernate 3.0.5
J'ai parfois l'erreur suivante qui apparait dans mon application
Code:
Caused by: org.hibernate.AssertionFailure: collection was not processed by flush()
at org.hibernate.engine.CollectionEntry.postFlush(CollectionEntry.java:144)
at org.hibernate.event.def.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:305)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:28)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
at org.springframework.orm.hibernate3.HibernateTemplate$27.doInHibernate(HibernateTemplate.java:771)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:358)
at org.springframework.orm.hibernate3.HibernateTemplate.flush(HibernateTemplate.java:769)
at com.bodet.open.domaine.administration_terminal.fabrique.hibernate.SalarieTerminalFabriqueHib.modifier(SalarieTerminalFabriqueHib.java:86)
at com.bodet.open.domaine.administration_terminal.fabrique.hibernate.SalarieTerminalFabriqueHib$$FastClassByCGLIB$$d7b72c31.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:698)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:122)
at com.bodet.open.domaine.framework.fabrique.intercepteur.FabriqueInterceptor.internalInvoke(FabriqueInterceptor.java:354)
at com.bodet.open.domaine.framework.fabrique.intercepteur.FabriqueInterceptor.invoke(FabriqueInterceptor.java:179)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:643)
at com.bodet.open.domaine.administration_terminal.fabrique.hibernate.SalarieTerminalFabriqueHib$$EnhancerByCGLIB$$98530904.modifier(<generated>)
Cette erreur est déjà référencée dans quelques posts :
http://forum.hibernate.org/viewtopic.ph ... ionfailure
http://forum.hibernate.org/viewtopic.ph ... ionfailure
En creusant un peu j'ai trouvé le problème. J'ai un listener de postUpdate. Dans la méthode onPostUpdate je compare l'ancienne propriété à la nouvelle. Si la propriété correspond à une entité peristante gérée par hibernate, lors de cette comparaison, l'appel à equals initialise l'entité persistante. Du coup, dans le postFlush hibernate retrouve des collections sur cette entité qui n'ont pas été traitées par le flush car elles ont été initialisées après le flush.
Comment éviter cela ? Le but du postUpdate est de manipuler les objets d'hibernate pour réaliser des traitements dessus (log des modifications dans mon cas). Y a t'il des recommandations concernant le code que l'on met dans le postUpdate.
Plus généralement je trouve que l'utilisation des listeners dans hibernate est assez sensible. Il y a vite des effets de bords. Il serait intéressant d'avoir des recommandations plus précises sur l'utilisation des listeners
Seb