IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Java Discussion :

Spring + hibernate + sessionInViewFilter : problème d'autogoal avec flush


Sujet :

Spring Java

  1. #1
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut Spring + hibernate + sessionInViewFilter : problème d'autogoal avec flush
    Bonjour,

    Continuant mon apprentissage de spring et hibernate, j'ai découvert un truc qui m'a passablement effrayé:

    Un objet attaché à une session hibernate se sauve automatiquement lorsque la session est flushé. Mon problème c'est que souvent, il arrive que je commence à modifier un objet que j'ai au préalable chargé puis qu'entre temps je fasse appel à d'autres méthodes DAO (par ex. pour des tests), dont certaines contiennent des find qui peuvent déclencher un flush.

    Si cela arrive, hibernate essaie de sauver un objet que j'ai pas fini de retoucher, déclenchant des problèmes de not null etc....

    Le rêve serait que hibernate ne fasse jamais d'update sans que je le demande explicitement mais d'après le forum d'hibernate c'est impossible, celui qui a demandé ça s'est limite fait insulté par des intégristes.

    Eventuellement, j'arriverai à maitriser le problème entre ma couche business et les couches DAO inférieures. Mais par contre, si l'entité est manipulée par l'UI et que l'UI fait un appel à une classe business pendant qu'elle est en train de bricoler avec, ça va poser problème.

    J'utilise un sessionInViewFilter fourni par Spring, j'ai pensé que mettre singleSession à false pourrait peut être aidé et me permettre d'avoir des sessions par transaction applicative (Un appel vers une classe business = une session) mais je suis pas sûr des effets de bord.

    Est-ce une bonne solution? Quelqu'un pourrait m'éclairer un peu sur le sujet? Ce serait cool merci.

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Le problème ne vient pas d'Hibernate mais de la façon dont tu gères tes sessions / transaction.
    Si tu ne commit pas ta transaction ou ne demandes pas un flush explicite, Hibernate ne le fera pas.

  3. #3
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Le problème ne vient pas d'Hibernate mais de la façon dont tu gères tes sessions / transaction.
    C'est vrai, néanmoins ça me préoccupe.

    Si tu ne commit pas ta transaction ou ne demandes pas un flush explicite, Hibernate ne le fera pas.
    Si justement....
    Certaines opérations faites avec la session déclenchent automatiquement un flush. Et dans ce flush sont pris les changements même partiels effectués sur les entités.

  4. #4
    Inactif  
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    2 189
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 189
    Points : 2 336
    Points
    2 336
    Par défaut
    Citation Envoyé par _skip Voir le message
    C'est vrai, néanmoins ça me préoccupe.



    Si justement....
    Certaines opérations faites avec la session déclenchent automatiquement un flush. Et dans ce flush sont pris les changements même partiels effectués sur les entités.
    Peut être que ce sujet pourra t'intéresser

    http://forum.springframework.org/arc...p/t-11200.html

    Mais j'ai une question, tu gères manuellement tes session ou passes tu par getHibernateTemplate ?

  5. #5
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    - soit tu gères l'ordre de tes instructions (si possible) pour éviter de déclencher le flush
    - soit tu utilises le setFlushMode sur la session (voir paragraphe sur le flush dans la doc), pour que le flush ne se produise qu'au commit de ta transaction, ou par appel explicite à la méthode flush.

  6. #6
    Inactif  
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    2 189
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 189
    Points : 2 336
    Points
    2 336
    Par défaut
    la gestion manuelle est déconseillé à mon avis ca donne du code sale et c'est difficile à maintenir pour ceux qui ne connaissent pas la séquence par coeur

    l'utilisation du transaction manager avec la définition de la propagation doit à mon avis résoudre 99,9 % des cas (ou de l utilisation de l'annotation driven) le tout couplé à HibernateTemplate et OpenSessionInViewFilter


    je comprend pas l utilisation d un flush pour des find ... si tu vas au supermarché tu vas payé pour le prix posé sur l étiquette non pas celui est définit en coulisse par le management il y a que des cas d utilisation très critique comme celui d un site de vente aux enchères mais je pense pas que ca cadre avec les besoins de tes clients ...

  7. #7
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Merci à vous 2,

    Dans le comportement par défaut d'hibernate si j'ai bien compris la doc, un flush de session est effectué *automatiquement* avant les opérations de recherches et de bulkupdate afin de s'assurer que ces dernières ne prendront pas en compte des données qui sont censées ne plus exister ou avoir été modifiées par du précédent code.

    C'est ce qui fait, que, tranquillement en train de modifier mon entité, j'ai soudainement fait un appel vers une classe DAO qui a déclenché un flush sans que je le demande, et vu que j'avais encore des choses à faire sur l'entité avant de la sauvegarder (2 lignes plus bas) ça m'a fait une violation d'intégrité.

    PS: J'ai utilisé le paramètre singleSession=false dans le Filtre spring et ça fait ce que je demande. Ca ne change rien au fait que je trouve cette *magie* de sauvegarde automatique des entités changées affreusement mal venue et bien plus sujette à déclencher des situations inattendues qu'à amener quoi que ce soit de bon. J'ai encore cherché toute la soirée comment désactiver ça, sans succès.

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par _skip Voir le message
    PS: J'ai utilisé le paramètre singleSession=false dans le Filtre spring et ça fait ce que je demande. Ca ne change rien au fait que je trouve cette *magie* de sauvegarde automatique des entités changées affreusement mal venue et bien plus sujette à déclencher des situations inattendues qu'à amener quoi que ce soit de bon. J'ai encore cherché toute la soirée comment désactiver ça, sans succès.
    c'est votre méthodologie de modification des entités qui est "erronée"…

    essayez de voir une méthode qui met à jour les champs d'un POJO comme une routine de noyau qui bloque les interruptions : ça doit être le plus court possible…

    tout ce qui est nécessaire à la modification des champs doit avoir été collecté avant de commencer…
    et une fois les modifications commencées, il faut éviter tout round-trip vers le repository…

  9. #9
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    tout ce qui est nécessaire à la modification des champs doit avoir été collecté avant de commencer…
    et une fois les modifications commencées, il faut éviter tout round-trip vers le repository…
    Oui c'est vers cela que je me tourne au vu de ces récentes découvertes.

    Ca veut aussi dire que c'est pas tant bien que je laisse l'UI avoir accès à des objets managés par hibernate si j'extrapole.
    Du temps ou je bossais avec .Net j'ai toujours utilisé une business façade et des entités déconnectées. Je sais pas pourquoi je me suis mis dans la tête avec hibernate de faire du full OO en profitant du lazy loading et tout ça...

  10. #10
    Inactif  
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    2 189
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 189
    Points : 2 336
    Points
    2 336
    Par défaut
    Citation Envoyé par _skip Voir le message
    Oui c'est vers cela que je me tourne au vu de ces récentes découvertes.

    Ca veut aussi dire que c'est pas tant bien que je laisse l'UI avoir accès à des objets managés par hibernate si j'extrapole.
    Du temps ou je bossais avec .Net j'ai toujours utilisé une business façade et des entités déconnectées. Je sais pas pourquoi je me suis mis dans la tête avec hibernate de faire du full OO en profitant du lazy loading et tout ça...
    ca me semble vraiment bizzard les problèmes que tu rencontres, bien sur qu'avec jsf / icefaces - spring - hibernate tu peux faire du full oo

    montre voir un peu de code jsf, managed bean, business service et dao que tu utilises

Discussions similaires

  1. Réponses: 1
    Dernier message: 06/08/2014, 09h23
  2. [Integration] Problème d'intégration d'un Applet JAVA tournant avec Spring / Hibernate / JPA
    Par anthony22360 dans le forum Spring
    Réponses: 1
    Dernier message: 02/07/2013, 16h41
  3. Problème d'entité inconnue avec Spring/Hibernate
    Par Yann1213 dans le forum Spring Web
    Réponses: 6
    Dernier message: 08/01/2013, 12h49
  4. Problème avec JSF + Spring + Hibernate
    Par chahrazedd dans le forum JSF
    Réponses: 1
    Dernier message: 31/07/2011, 15h38
  5. [Data] Problème de lazy avec hibernate et Spring
    Par Invité dans le forum Spring
    Réponses: 3
    Dernier message: 20/02/2008, 20h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo