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 :

Foreign key constraint fails


Sujet :

JPA Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 188
    Par défaut Foreign key constraint fails
    Je voudrais

    J'ai une entité Cocktail et une entité CategorieCocktail.
    Un Cocktail a plusieurs catégories et une catégorie peut avoir plusieurs cocktails.

    J'ai une table cocktail avec pour colonnes ( id, name, recette),
    une table categoriecocktail avec (id, name)
    une table belong_to avec 2 colonnes (cocktail_id, categorie_id)

    Je veux pouvoir créer des nouveaux cocktails en choisissant un name, une recette et une liste de catégories. Pour cela, mes catégories existent déjà en base.


    Le problème est lorsque je désire persister mon nouveau cocktail dans la base, il y a un problème de transient object car par persistance, l'entitymanager veut insérer une nouvelle fois les catégories sélectionnées pour le cocktail.

    Je voudrais éviter de devoir créer un POJO Cocktailcategorie avec pour attributs les 2 clés primaires. Il faut en fait qu'une ligne soit insérée dans la table cocktail aveec le name et la recette et qu'une ligne soit mise par catégorie sélectionnée dans la table belong_to.

    Est-ce possible de faire ceci sans nouveau POJO?

    Merci

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    @Entity
    @Table(name="cocktail")
    public class Cocktail {
     
    	@Id
    	@Column(name = "id", nullable = false)
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private Integer id;
     
    	@Column(name = "name", nullable = false, unique = true)
        private String nomCocktail="";
     
    	@Column(name = "recipe", nullable = false)
        private String recette="";
     
     
    	 // relation Cocktail (many) -> Categorie (many) via une table de jointure belong_to
    	 // belong_to(category_id) est clé étangère sur CategorieCocktail(id)
    	 // belong_to(cocktail_id) est clé étangère sur Cocktail(id)
    	 // cascade=CascadeType.PERSIST : persistance d'1 cocktail entraîne celle de ses categories
    	 @ManyToMany(cascade={CascadeType.PERSIST})
    	 @JoinTable(name="belong_to",inverseJoinColumns = @JoinColumn(name = "category_id"))
    			 //joinColumns = @JoinColumn(name = "cocktail_id"),
     
    private List<CategorieCocktail> categoriescocktails = new ArrayList<CategorieCocktail>();
     
        /* constructeurs... getters setters 
         */
     
     
    		public List<CategorieCocktail> getCategoriescocktails() {
    			return this.categoriescocktails;
    		}
     
     
    		public void setCategoriescocktails(List<CategorieCocktail> entrees) {
    			this.categoriescocktails = entrees;
    		}
    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
     
     
     CategorieCocktail.java
    @Entity
    @Table(name="cocktail_category")
    public class CategorieCocktail {
    	@Id
    	@Column(name = "ID", nullable = false)
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private Integer id;
     
    	@Column(name = "name", nullable = false)
        private String nomCategorieCocktail="";
     
    	 // relation Categorie (many) -> Cocktail (many) via une table de jointure belong_to
    	 // belong_to(category_id) est clé étangère sur CategorieCocktail(id)
    	 // belong_to(cocktail_id) est clé étangère sur Cocktail(id)
    	  //cascade=CascadeType.PERSIST : persistance d'1 cocktail entraîne //celle de ses categories
    	 @ManyToMany(cascade={CascadeType.PERSIST})
    	 @JoinTable(name="belong_to",joinColumns = @JoinColumn(name = "category_id"),
    	inverseJoinColumns = @JoinColumn(name = "cocktail_id"))
    	 private Set<Cocktail> cocktails = new HashSet<Cocktail>();
     
      constructeur et getters...

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 188
    Par défaut
    En attendant, j'ai crée un nouveau POJO CocktailCategoryID.

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    @Entity
    @Table(name="belong_to")
    public class CategoryCocktailId {
     
    	@Embeddable
    	public static class Id implements Serializable {
     
    		@Column(name = "cocktail_id", nullable = false)
    		private Integer cocktail_id;
     
    		@Column(name = "category_id", nullable = false)
    		private Integer category_id;
     
    // getters et setters
    	}
     
    	@EmbeddedId
    	public Id id = new Id();
     
    	@ManyToOne()
    	@JoinColumn(name="cocktail_id",insertable=false,updatable=false)
    	private Cocktail cocktail;
     
    	@ManyToOne()
    	@JoinColumn(name="category_id",insertable=false,updatable=false)
    	private CategorieCocktail categorie;
     
     
    	public CategoryCocktailId()  {
     
    	}
     
    	public CategoryCocktailId(Cocktail cocktail, CategorieCocktail categorie) {
    		getId().setCategory_id(category.getId());
    		getId().setCocktail_id(cocktail.getId());
     
    		this.setCategorie(categorie);	
    		this.setCocktail(cocktail);
    		//this.cocktail.getCategoriescocktails().add(categorie);
    	}
     
    //getters et setters
     
    }
    Malheureusement, j'ai une erreur lorsque je veux persister un objet CategoryCocktailId dans ma table belong_to malgré que l'objet soit bien rempli.

    Voici le test:

    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
     
     
    	// contexte de persistance
    		EntityManager em = getEntityManager();
    		// création personnes
    		cat1= new CategorieCocktail("tonique");
    		EntityTransaction tx = em.getTransaction();
    		tx.begin();
    		// persistance des objets
    		em.persist(cat1);
    		tx.commit();
     
    		c1 = new Cocktail("cocktail01", "Versez le jus");
     
    		tx.begin();
    		em.persist(c1);
    		tx.commit();
     
    // tout se passe bien jusque ici
     
    		CategoryCocktailId catcock = new CategoryCocktailId(c1,cat1);
    		tx.begin();
    		em.persist(catcock);
    		tx.commit();
    // le test plante au dernier commit et le message d'erreur est-ci dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Exception in thread "main" javax.persistence.RollbackException: Error while commiting the transaction
    ....
    Caused by: org.hibernate.exception.ConstraintViolationException: Could not exe...cute JDBC batch update
    	
    Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`jpa`.`belong_to`, CONSTRAINT `FKD2D27D7B2A5306E7` FOREIGN KEY (`cocktail_id`) REFERENCES `cocktail` (`id`))
    	at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1213)
    	at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:912)
    	at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
    	... 10 more
    Je n'ai jamais défini ce n° de contrainte quelque part. Je ne sais pas d'où cela vient. C'est une ligne qui se rajoute dans la table TABLE_CONSTRAINTS.

    VOici la syntaxe de création de mes tables:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CREATE TABLE cocktail (id INT NOT NULL AUTO_INCREMENT, name TEXT, recipe TEXT, PRIMARY KEY(id));
     
    CREATE TABLE cocktail_category (id INT NOT NULL AUTO_INCREMENT, name TEXT, PRIMARY KEY(id));
     
    CREATE TABLE belong_to (cocktail_id INT NOT NULL, category_id INT NOT NULL, PRIMARY KEY (cocktail_id, category_id));
    Quelqu'un a une idée?
    Merci

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    188
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 188
    Par défaut
    J'ai trouvé une solution qui permet d'éviter d'écrire un nouveau POJO.
    http://www.java2s.com/Tutorial/Java/...JoinColumn.htm

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 13
    Dernier message: 27/08/2015, 17h46
  2. Réponses: 3
    Dernier message: 28/11/2011, 17h26
  3. [PHP 5.3] [ADOdb] a foreign key constraint fails
    Par Neuromancien2 dans le forum Langage
    Réponses: 0
    Dernier message: 15/05/2011, 17h10
  4. Réponses: 0
    Dernier message: 12/12/2007, 21h10
  5. [clés étrangères] a foreign key constraint fails
    Par guidav dans le forum Débuter
    Réponses: 15
    Dernier message: 09/08/2006, 23h50

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