-
Un flush non désiré
Bonjour :)
Je bute sur un problème de logique d'utilisation Hibenate, ça doit pourtant être facile mais voilà, si vous pouvez me renseigner...
Il s'agit d'une appli web assez standard (struts, hibernate, spring).
Voici le comportement que je souhaiterai avoir, je viens d'une page de modification d'un objet et je le sauvegarde :
1) J'arrive dans l'action, mon objet métier est attaché à la session Hibernate
2) je fais des modifications dessus d'après les données du formulaire Struts
3) j'ai besoin de faire des tests sur l'objet avant sauvegarde, il me faut l'objet en l'état avant sauvegarde. Je récupère donc un autre objet avec un load(), je le détache de la session, puis je compare l'objet initial et l'objet à sauvegarder
4) si tout est ok, je laisse l'objet se sauvegarder. Sinon, une exception permet de revenir vers l'écran de saisie.
Mon problème c'est le 3). Si je demande à Hibernate de charger le même objet déjà en session mais dans son état initial, il détecte que des modifications ont eu lieu et me fait un session.flush avant mon load (du coup, l'objet se sauvegarde tout seul avant de commencer les tests !).
Comment puis-je éviter ce comportement ?
Est-ce que c'est une mauvaise utilisation d'Hibernate que d'avoir 2 objets identiques à gérer mais dans un état différent, l'un à sauvegarder, et l'autre pour comparer ? Si oui, avez vous une meilleur pratique à me conseiller ?
Merci d'avance ! :coucou:
-
Pourquoi ne gardes tu pas, ton objet hibernate et un objet similaire mais non rattaché à ta session.
Comme ça tu ne modifies que ton objet hibernate en fonction de tes critères.
-
Ta proposition me semble pas trop mal. :) Je suis donc parti sur cette modification :
Au chargement d'une page d'édition, on clone l'objet pour le réutiliser plus tard.
A la validation de cette édition, on récupère la copie depuis le formulaire struts et on ne la rattache pas à la session contrairement à l'objet à sauver.
Maintenant, j'ai quand même un autre soucis. A l'étape 3, j'ai une vérification à faire sur une autre entité de la base que je charge avec un load... Et surprise, Hibernate fait aussi ses updates sur mon objet métier.
En fait, dès qu'on fait appel à Hibernate, quelle que soit l'opération, ça synchronise les objets et la base ? :?
Je pourrais m'arranger pour faire tous les appels à la base avant de changer quoi que ce soit dans mes objets mais ça me fait revoir ma conception ; et puis c'est plutôt contraignant comme usage je trouve....
Une idée ?
-
J'ai trouvé une solution :
Dans les load(), je rajoute :
getHibernateTemplate().setFlushMode(HibernateTemplate.FLUSH_NEVER);
Et dans le save(), je rajoute :
getHibernateTemplate().setFlushMode(HibernateTemplate.FLUSH_AUTO);
-
Je trouve ça étonnant que ce soit le load qui déclenche un flush à la base.
Comment sont gérées tes sessions ? Si le load déclenche un flush, c'est que tu utilises la même session entre deux appels HTTP, sinon, avec une nouvelle session, tout les objets seraient considérés comme détachés. C'est peut être une bonne piste, étant donné que le pattern consistant à ouvrir une session à la portée du traitement d'une requête HTTP est très répandu.