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

Hibernate Java Discussion :

commit , violation de contraite d'intétrité


Sujet :

Hibernate Java

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut commit , violation de contraite d'intétrité
    Bonjour,

    J'ai deux table A et B.
    La B contient l'identifiant d'une ou plusieurs instances de A
    B a une contraite d'intégrité : l'identifiant de A doit exister

    j'ai donc une relation OnetoMany

    Lorsque je fait un save d'un objet A , puis un save de plusiurs objets B qui contiennent l'identifiant A et que je fais un commit , j'ai une erreur de violation de l'intégrité au commit() me disant que le parent n'existe pas.

    En effet , le commit de A n'as pas encore eu lieu mais A a été sauver pourtant.

    comment faire pour ne faire qu'un commit et ne pas violer ka contraite ?
    Pourquoi apres le save , l'objet A n'est t'il pas considéré comme étant en base ?

  2. #2
    Membre éclairé Avatar de BizuR
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    688
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 688
    Points : 757
    Points
    757
    Par défaut
    Pour ne pas laisser A être sauvegardé par Hibernate lui même ?!?
    J'avais déjà eu ce problème également mais pour ma part cela se justifiait par un modele avec double contrainte d'integrité (B vers A et A vers B )

    Ici le problème est assez classique. Toutefois il est possible qu'il était demandé un commit() pour que la sauvegarde fonctionne. Si tu veux tout faire d'une traite , ajoute en attribut de la relation One-to-many : cascade="insert-update" pour que tu n'aies qu'a demander les sauvegardes de B et tout devrait rentrer dans l'ordre
    See you, space cowboy... and if you're satisfied, click on

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut
    bonjour,

    Merci de ta réponse mais cela ne résoud pas la violation de contraite.
    Ce qui est bizarre , c'est que les save() se font sans problème.
    C'est au niveau du Commit() que la violation apparait.

    a noter que j'ai mis cascade="save-update" , "insert-update" n'existe pas.

    J'ai trouvé sur un site que l'on pouvait faire un session.persist() mais la methode persist() n'existe pas pour une session.

    Bref , j'ai toujours ma violation ...

  4. #4
    Membre éclairé Avatar de BizuR
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    688
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 688
    Points : 757
    Points
    757
    Par défaut
    Au temps pour moi, je ne me souvenais plus exactement (et du coup j'ai mis insert à tous mes posts en parlant depuis hier soir ... durdur ).

    Ca me parait tout de même étrange car j'ai EXACTEMENT le même système de mon coté et tout fonctionne sans aucun problème. Peut-on voir ton mapping et la classe sauvegardant les données ? Peut on aussi avoir la trace de l'erreur exacte ?

    Merci bien
    See you, space cowboy... and if you're satisfied, click on

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut
    voici l'erreur :

    Caused by: java.sql.BatchUpdateException: ORA-02291: violation de contrainte (PLSVISTA.FKABBFA7A42509EE) d'intégrité - touche parent introuvable

    La contraite sql :

    ALTER TABLE COMMANDE ADD CONSTRAINT FKABBFA7A42509EE
    FOREIGN KEY (ID_BL)
    REFERENCES PLSVISTA.BON_LIVRAISON (ID_BL) ;

    L'association de la classe B :

    <!-- Associations -->
    <many-to-one name="bonLivraison" class="org.ultimania.model.BonLivraison" column="ID_BL" cascade="save-update" />

    La classe A :

    <class name="org.ultimania.model.BonLivraison" table="BON_LIVRAISON"
    lazy="true">
    <!-- where="ETAT=0" dynamic-update="true" dynamic-insert="true" -->
    <id name="idBl" type="java.lang.Long" column="ID_BL">
    <generator class="sequence">
    <param name="sequence">SEQ_ID_BON_LIVRAISON</param>
    </generator>

    <!--
    <set name="commandes">
    <key column="ID_BL" />
    <one-to-many class="org.ultimania.model.Commande" />
    </set>
    -->


    a noter que ce set est en commentaire ...

  6. #6
    Membre éclairé Avatar de BizuR
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    688
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 688
    Points : 757
    Points
    757
    Par défaut
    1/ Un tit peu de formatage de ton post serait le bienvenue (tag CODE surtout)
    2/ Dans le cas où le set n'est pas en commentaire, tu as ici une relation 1..N bidirectionnelle si je ne m'abuse. Il manque donc un inverse=true sur l'une des deux parties (dans le set par exemple).

    Sinon de mon côté j'ai exactement la même chose avec une entité CONTRAT et TYPE_CONTRAT et cela fonctionne sans aucun problème... cela dit, je faisais peut être le commit avant pour faciliter l'enregistrement. Cependant, je ne faisais plus de la même manière dans mon second cas où je n'enregistrais QUE l'entité mère avec tout ses nouveaux objets rattachés, et l'ensemble fonctionnait à merveille... c'est vraiment étrange.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <!--Champ de type Antecedent-->
    <many-to-one name="antecedent" column="ANTCDT" cascade="save-update"/>
    Normalement, dans les logs,on voit qu'il enregistre et met à jour tous les fils avant d'enregistrer le père...
    See you, space cowboy... and if you're satisfied, click on

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut
    En fait , je ne peux pas décommenté le set.
    je ne comprends pas bien ce set.

    Je fais un session.flush() apres session.save(A);

    puis je fais un session.flush() apres session.save(b) mais là j'ai une erreur il me dit parent key not exist

    pourtant le flush() apres le save(A) aurait du m'insérer A !

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut set
    je commence à comprendre la bidirectionalité généré par le set et une relation one-to-many

    Mais je ne sais pas ce que je dois mettre dans le POJO du pere

    private ArrayList child ?

    pour pouvoir faire lke add(c);

    Parent p = .....;
    Child c = new Child();
    p.getChildren().add(c);
    session.save(c);
    session.flush();

    voir
    http://www.hibernate.org/hib_docs/v3...rentchild.html

  9. #9
    Membre éclairé Avatar de BizuR
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    688
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 688
    Points : 757
    Points
    757
    Par défaut
    ArrayList n'hérite pas du Set, il faut plutot que tu déclares un objet Collection très général dans ta classe (private Collection childs; ) et que tu utilises, actuellement (puisque tu mappes avec un set) un objet implémentant la classe Set, par exemple un HashSet. Tu pourras ainsi utiliser les fonctions que tu désires.
    See you, space cowboy... and if you're satisfied, click on

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut
    J'ai mis le set avec un HashSet et j'ai fait

    parent.getCommandes().add(comm);
    save(child);
    save(parent);

    puis l'inverse save(child); puis save(parent);

    j'ai une belle exception :

    exception setting property value with CGLIB : setter of org.ultimania.model.BonLivraison.setCommandes

    a priori je n'ai pas besoin d'une relation bidirectionnelle mais le cascade="save-update" n'as pas marché.

    Je suis un peu bloqué car je ne peux faire le commit que si les enfants ont été commité.

  11. #11
    Membre éclairé Avatar de BizuR
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    688
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 688
    Points : 757
    Points
    757
    Par défaut
    Ce qui ne présente pas forcément une gêne en soi mais plus un problème d'intégrité ... tu peux toujours faire toi même un rollback manuel en cas de problème lors du second commit

    Etrange tout de même que cela ne fonctionne pas :
    http://www.hibernate.org/hib_docs/v3...child-cascades
    See you, space cowboy... and if you're satisfied, click on

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut
    oui mais je ne peut pas faire de commit sur le pere car je ne pourrai pas faire un delete puis un nouveau commit du delete dans l'hypothese ou je ferai un rollback du fils.

  13. #13
    Membre éclairé Avatar de BizuR
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    688
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 688
    Points : 757
    Points
    757
    Par défaut
    Si je pense que c'est possible ainsi :

    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
     
    public void saveGraphe(...){
         (...)
         boolean filsOK = false;
         try{ (...)
              session.save(fils);
              session.commit();
              filsOK = true;
              session.startTransaction();
              session.save(pere);
              session.commit();
         } catch (HibernateException e) {
              session.rollback();
              if (filsOK){
                   deleteFils(fils);
              }
         }
         (...)
    }
     
    public void deleteFils(Fils fils){
         session.startTransaction();
         try{
              session.delete(fils);
              session.commit();
         } catch(HibernateException e){
              session.rollback();
         }
    }
    Et ca devrait marcher je pense
    Par contre je suis tout a fait conscient que ca tient de la bidouille plus qu'autre chose mais bon, c'est toujours mieux que rien... si jamais tu crains réellement d'un point de vue intégrité des données.
    See you, space cowboy... and if you're satisfied, click on

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut
    Merci , j'utiliserai cette solution entout dernier recours.
    En fait mon probleme est plus compliqué car le fils a des petits fils , la cascade est donc un peu lourde pour 3 generations.

  15. #15
    Membre éclairé Avatar de BizuR
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    688
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 688
    Points : 757
    Points
    757
    Par défaut
    En effet ... ca pose problème si il y a plusieurs niveaux je pense. Mais si tes petits fils sont en save-update également, je me demande pourquoi un tel problème justement ... peut-être une lacune d'Hibernate ?!?
    See you, space cowboy... and if you're satisfied, click on

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut
    je ne sais pas mais cela ne m' arange pas.

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut
    oui , mais que puis-je faire ?

  18. #18
    Membre éclairé Avatar de BizuR
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    688
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 688
    Points : 757
    Points
    757
    Par défaut
    Essaie peut etre de t'interesser aux triggers applicatifs fournis par Hibernate ([Pre|Post][Insert|Update|Delete|Load]EventListener) dans le but de capter le flux et enregistrer auparavant les fils et sous-fils si l'objet sauvegardé est de type Personne.

    Ce qui donnerait grossièrement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if (obj instanceof Personne){
         session.save((Personne)obj.getFils());
    } elseif (obj instanceof Fils){
         session.save((Fils)obj.getPetitFils());
    }
    Dans tes requêtes d'insert (pre) et update (pre) notamment
    Pour plus d'informations, cf. Doc hibernate.
    See you, space cowboy... and if you're satisfied, click on

  19. #19
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 52
    Points : 28
    Points
    28
    Par défaut
    Salut,

    J'ai trouvé mon erreur , j'avais un trigger qui incrémenter l'id du père sur la base de donnée.
    D'où la violation de contrainte.

  20. #20
    Membre éclairé Avatar de BizuR
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    688
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 688
    Points : 757
    Points
    757
    Par défaut
    "Ca c'est ballot" comme dirait l'autre ... vive les triggers !
    See you, space cowboy... and if you're satisfied, click on

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. insertion, violation de contraint et commit
    Par elkamaro dans le forum Administration
    Réponses: 17
    Dernier message: 05/01/2010, 17h23
  2. Interbase en réseau:commit ne s'appliquent pa aux autres pc?
    Par Harry dans le forum Bases de données
    Réponses: 9
    Dernier message: 27/05/2004, 14h10
  3. Query Begin et Commit son sur un bateau....
    Par faoz75 dans le forum Requêtes
    Réponses: 5
    Dernier message: 15/08/2003, 11h48
  4. commit et rollback....?
    Par The_Nail dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 06/06/2003, 14h36
  5. Réponses: 3
    Dernier message: 22/05/2002, 09h37

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