-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Chargement d'objets lazy dans onPostUpdate
PostPosted: Tue Oct 18, 2005 4:05 am 
Expert
Expert

Joined: Thu Sep 04, 2003 8:23 am
Posts: 368
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

_________________
Seb
(Please don't forget to give credits if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 18, 2005 10:11 am 
Expert
Expert

Joined: Thu Sep 04, 2003 8:23 am
Posts: 368
Bon je m'enfonce petit à petit dans les tréfonds d'hibernate pour comprendre ce qui se passe.

Apparament, les méthodes onPreUpdate/onPostUpdate sont sensibles car tous les tests de dirtyChecking ont été faits au préalable. Du coup, je me suis rabattu sur le bon vieux interceptor et sa méthode onFlushDirty. Lorsque cette méhode est appelée il semble encore être autorisé d'initialiser des entités. Du coup, je n'ai plus le problème ci-dessus.

Par contre j'arrive sur un second problème : je ne suis pas notifié lorsqu'une entité est ajoutée/supprimée dans une collection liée à une objet métier. J'ai trouvé un poste qui disait qu'il fallait pour cela ajouter un numéro de version à mon objet métier. C'est ce que j'ai fait. Du coup, la méthode onFlushDirty est maintenant appelée sur l'objet parent lorsque l'on ajoute/supprime un objet enfant à la collection.

Il me reste alors un dernier problème. Dans les paramètres de la méthode onFlushDirty il y a les valeurs avant et les valeurs après. Pour ma collection, la valeur avant et la valeur après ont la même référence mémoire ! Du coup, je suis incapable de connaître ce qui a été fait sur ma collection.

Est ce que quelqu'un connaît un moyen pour connaître les modifications effectuées à une collection dans hibernate.

Je suis rendu à me dire qu'il faudrait que je récupères le snapshot de la PersistentCollection dans le onFlushDirty et que je fasse une comparaison avec ce snapshot. Deux problèmes ici :
- le type du snapshot et la façon dont on récupère les données sont dépendants de la classe qui implémente PeristentCollection. Si hibernate ajoute en interne une nouvelle implémentation je devrais modifier mon code
- Je ne sais pas si j'ai le droit de manipuler le snapshot d'une collection

Si quelqu'un peut me dire si je suis dans une bonne voie cela m'arrangerait

Merci

_________________
Seb
(Please don't forget to give credits if you found this answer useful :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.