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

JPA Java Discussion :

Insertion en cascade


Sujet :

JPA Java

  1. #1
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut Insertion en cascade
    Bonjour,

    j'ai 2 tables livres et abonnes reliées entre elles par une relation n-n. J'ai donc une table emprunt qui joue le rôle de cette association. Cette table comprend la clé composite ainsi qu'une colonne annexe rajoutée.

    Via JPA, je cherche à créer un emprunt et à le persister en cascade dans les tables abonnes et livres.

    Dans mon entité Emprunt, j'ai donc ceci :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    @ManyToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name = "abonne_id", updatable=false, insertable=false)
    private Abonne abonne;
     
    @ManyToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name = "livre_id", updatable=false, insertable=false)
    private Livre livre;

    Dans mon entité emprunt, j'ai créé un constructeur prenant en params un abonne, un livre et ma colonne annexe (test).

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
      public Emprunt(Abonne abonne, Livre livre, String test) {
        	this.abonne = abonne;
        	this.livre = livre;    	
        	this.setTest(test);
     
        	getId().setAbonneId(abonne.getId());
        	getId().setLivreId(livre.getId());
     
        	abonne.getEmprunts().add(this);
        	livre.getEmprunts().add(this);
        }

    je cherche donc à persister une seule fois pour les 3 tables en faisant ceci :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Abonne a = new Abonne();
    a.setNom("test");
    a.setPrenom("test");
     
    Livre l = new Livre();
    l.setLibelle("test");
     
    Emprunt e = new Emprunt(a, l, "test");
    em.persist(e);

    J'obtiens une MySQLIntegrityConstraintViolationException. Cela est du je pense au fait que l'emprunt est inséré avant les livres et l'abonne en base. Ca correspondrait bien à l'exception mais je croyais que JPA devait pouvoir connaitre l'ordre d'insertions en base selon les annotations ? En tout cas dans une relation 1-n sans table d'association, lorsque j'essaie d'insérer les fils avant le père, JPA m'insérer bien le père avant...

    Aucun problème si je procède ainsi, les valeurs sont insérées dans les 3 tables :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Abonne a = new Abonne();
    a.setNom("test");
    a.setPrenom("test");
     
    Livre l = new Livre();
    l.setLibelle("test");
     
    em.persist(a);	
    em.persist(l);		
     
    Emprunt e = new Emprunt(a, l, "test");
    em.persist(e);

    Est ce possible donc dans une relation n-n avec table d'association d'insérer dans les 3 tables avec un seul persist en jouant avec l'attribut cascade ?


    Merci

  2. #2
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mars 2008
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2008
    Messages : 70
    Par défaut
    Juste une question ,

    Lorsque tu as une relation n/n avec une table qui représente l'association ( obligatoire forcément ) , si tu associe un livre à un abonné ( donc nouvel emprunt ) pour moi il n'y a que la table emprunt à mettre a jour non ?

    Je travail sur un proejt ou j'ai exactement ton cas et je ne mets à jour que la table d'association qui contient les deux clefs primaires ( qui forme la clef compiste ) des tables associées plus un petit attribut supplémentaire.

    Est ce necessaire de faire une insertion en cascade , d'ailleurs que mets tu a jour dans les tables livre et abonné ?

  3. #3
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Bonjour,

    Citation Envoyé par ramoucho75020 Voir le message
    Lorsque tu as une relation n/n avec une table qui représente l'association ( obligatoire forcément ) , si tu associe un livre à un abonné ( donc nouvel emprunt ) pour moi il n'y a que la table emprunt à mettre a jour non ?
    dans ce cas de figure ci, je suis entièrement d'accord avec toi mais je me suis probablement mal exprimé. En fait, je cherche à créer un emprunt "from scratch" où je n'ai ni abonne ni livre en base.

    J'arrive à créer 3 entités (abonne, livre et emprunt), à persister abonne et livre en base, à récupérer les id générés puis à persister emprunt avec ces id. Je persiste donc 3 fois.

    Ce que je souhaite faire, c'est créer ces 3 entités, puis à persister uniquement emprunt qui persistera livre et abonne en base par le jeu des cascades (il faudra donc persister livre et abonne avant). Cependant, j'obtiens une violation de contrainte car je pense qu'il essaie de persiter emprunt avant livre et abonne.

    Au final, je ne sais pas si c'est possible de faire ceci ou si je m'y prends mal...

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mars 2008
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2008
    Messages : 70
    Par défaut
    Je comprends mieux ,


    Je pense que dans ton cas ( à confirmer avec d'autres membres ) tu es obligé de faire les trois insert. Cependant tu peux a la limite les regrouper dans une transaction aisin tu va pouvoir définir l'odre des inserts et faire un rollback en cas d'echec de l'un des insert.

    Comme ca ton bloc est persisté en un seul coup, et en cas d'erreur sur l'un des insert tout est annulé grace au rollback.

    Je suis curieux de savoir si effectivement l'on peut faire ca directement en une fois via JPA. Peut etre que celà depend de l'ORM ....

  5. #5
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Citation Envoyé par ramoucho75020 Voir le message
    Peut etre que celà depend de l'ORM ....
    peut être

    Dans le cas d'une relation 1-n avec 2 tables donc, j'ai testé 1 seul persist et cela marche bien (que je persiste sur la table owner ou non). Je pensais donc reproduire ceci dans le cas d'une relation n-n mais sans succès jusque là.

    Au final, je suis pas bloqué bien sur, j'essaie juste de voir les possibilités offertes et de "bidouiller" un peu. Dans les rares exemples trouvés sur internet correspondant à mon cas, 3 persist sont utilisés...

    Merci de tes réponses en tout cas

  6. #6
    Membre averti
    Inscrit en
    Février 2011
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 18
    Par défaut
    Citation Envoyé par Madfrix Voir le message
    peut être

    Dans le cas d'une relation 1-n avec 2 tables donc, j'ai testé 1 seul persist et cela marche bien
    chez moi cela ne marche pas, avec par exemple ce cas :
    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
    CREATE TABLE mere (
    idmere INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    nom VARCHAR(50) NOT NULL,
    PRIMARY KEY(idmere)
    );
     
    CREATE TABLE fil (
    idfil INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    mere_idmere INTEGER UNSIGNED NOT NULL,
    nom VARCHAR(50) NOT NULL,
    PRIMARY KEY(idfil, mere_idmere),
    FOREIGN KEY(mere_idmere)
    REFERENCES mere(idmere)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION
    );

    voila mon topic ...

Discussions similaires

  1. Insertion cascade avec JPA ne marche pas
    Par marwen109 dans le forum JPA
    Réponses: 1
    Dernier message: 25/03/2012, 21h57
  2. [EJB3] Insertion en cascade
    Par nemesis74100 dans le forum Java EE
    Réponses: 16
    Dernier message: 17/04/2008, 17h58
  3. [SQL2K] Insert en cascade, trigger
    Par Faboul dans le forum Développement
    Réponses: 6
    Dernier message: 08/08/2007, 10h48
  4. [Postgresql] pb lors d'insertion de données
    Par bob20000 dans le forum Requêtes
    Réponses: 8
    Dernier message: 04/11/2002, 15h33
  5. Réponses: 4
    Dernier message: 28/09/2002, 00h00

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