+ Répondre à la discussion
Page 1 sur 2 12 DernièreDernière
Affichage des résultats 1 à 20 sur 21
  1. #1
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    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 chevronné Avatar de BizuR
    Inscrit en
    mai 2005
    Messages
    683
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : mai 2005
    Messages : 683
    Points : 720
    Points
    720

    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
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    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 chevronné Avatar de BizuR
    Inscrit en
    mai 2005
    Messages
    683
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : mai 2005
    Messages : 683
    Points : 720
    Points
    720

    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
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    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 chevronné Avatar de BizuR
    Inscrit en
    mai 2005
    Messages
    683
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : mai 2005
    Messages : 683
    Points : 720
    Points
    720

    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 :
    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
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    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
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    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 chevronné Avatar de BizuR
    Inscrit en
    mai 2005
    Messages
    683
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : mai 2005
    Messages : 683
    Points : 720
    Points
    720

    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
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    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 chevronné Avatar de BizuR
    Inscrit en
    mai 2005
    Messages
    683
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : mai 2005
    Messages : 683
    Points : 720
    Points
    720

    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
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    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 chevronné Avatar de BizuR
    Inscrit en
    mai 2005
    Messages
    683
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : mai 2005
    Messages : 683
    Points : 720
    Points
    720

    Par défaut

    Si je pense que c'est possible ainsi :

    Code :
    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
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    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 chevronné Avatar de BizuR
    Inscrit en
    mai 2005
    Messages
    683
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : mai 2005
    Messages : 683
    Points : 720
    Points
    720

    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
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    Par défaut

    je ne sais pas mais cela ne m' arange pas.

  17. #17
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    Par défaut

    oui , mais que puis-je faire ?

  18. #18
    Membre chevronné Avatar de BizuR
    Inscrit en
    mai 2005
    Messages
    683
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : mai 2005
    Messages : 683
    Points : 720
    Points
    720

    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 :
    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
    Futur Membre du Club
    Inscrit en
    juillet 2006
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : juillet 2006
    Messages : 52
    Points : 18
    Points
    18

    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 chevronné Avatar de BizuR
    Inscrit en
    mai 2005
    Messages
    683
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : mai 2005
    Messages : 683
    Points : 720
    Points
    720

    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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •