Problème d'insertion cascade avec JPA/TopLink [Résolu]

marwen109 64 Messages postés jeudi 12 août 2010Date d'inscription 26 mars 2012 Dernière intervention - 25 mars 2012 à 14:40 - Dernière réponse : marwen109 64 Messages postés jeudi 12 août 2010Date d'inscription 26 mars 2012 Dernière intervention
- 26 mars 2012 à 23:45
Bonjour a tous,
j'ai deux tables A et B comme suit:
CREATE TABLE A (
idA INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
PRIMARY KEY(idA)
);

CREATE TABLE B (
idB VARCHAR(20) NOT NULL,
A_idA INTEGER UNSIGNED NOT NULL,
name VARCHAR(30) NOT NULL,
PRIMARY KEY(idB, A_idA),
FOREIGN KEY(A_idA)
REFERENCES A(idA)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);



deux entités A.java et B.java :

A.java :
public class A implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name "IDA", nullable false)
private Integer ida;
@Basic(optional = false)
@Column(name "NAME", nullable false, length = 30)
private String name;
@OneToMany(cascade CascadeType.ALL, mappedBy "a")
private List bList;
//getters setters
}



BPK.java:

@Embeddable
public class BPK implements Serializable {
@Basic(optional = false)
@Column(name "IDB", nullable false, length = 20)
private String idb;
@Basic(optional = false)
@Column(name "A_IDA", nullable false)
private int aIda;

public BPK() {
}

public BPK(String idb, int aIda) {
this.idb = idb;
this.aIda = aIda;
}
//getters setters
}


B.java:
public class B implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected BPK bPK;
@Basic(optional = false)
@Column(name "NAME", nullable false, length = 30)
private String name;
@JoinColumn(name "A_IDA", referencedColumnName "IDA", nullable = false, insertable = false, updatable = false)
@ManyToOne(optional = false)
private A a;
//getters setters
}




lorsque j'essaye d'inserer des lignes :
EntityManagerFactory emf=Persistence.createEntityManagerFactory("threadPU");
EntityManager em=emf.createEntityManager();

A a=new A(null,"name1");

java.util.List lB=new ArrayList();

BPK bpk1 =new BPK();
bpk1.setIdb("idB1");
BPK bpk2 =new BPK();
bpk1.setIdb("idB2");
BPK bpk3 =new BPK();
bpk1.setIdb("idB3");

B b1=new B(bpk1,"name1");
B b2=new B(bpk2,"name2");
B b3=new B(bpk3,"name3");

b1.setA(a);
b2.setA(a);
b3.setA(a);

lB.add(b1);
lB.add(b2);
lB.add(b3);

a.setBList(lB);


em.getTransaction().begin();
em.persist(a);
em.getTransaction().commit();



j'ai l'erreur suivante :
Internal Exception: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "CONSTRAINT_42_1: PUBLIC.B FOREIGN KEY(A_IDA) REFERENCES PUBLIC.A(IDA)"; SQL statement:
INSERT INTO ABCD.PUBLIC.B (NAME, IDB, A_IDA) VALUES (?, ?, ?) [23506-164]
Exception in thread "main" javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "CONSTRAINT_42_1: PUBLIC.B FOREIGN KEY(A_IDA) REFERENCES PUBLIC.A(IDA)"; SQL statement:
INSERT INTO ABCD.PUBLIC.B (NAME, IDB, A_IDA) VALUES (?, ?, ?) [23506-164]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
Afficher la suite 

Votre réponse

5 réponses

marwen109 64 Messages postés jeudi 12 août 2010Date d'inscription 26 mars 2012 Dernière intervention - 26 mars 2012 à 23:45
+3
Utile
Enfin ,
simplement :
remplacer :
 @JoinColumn(name "A_IDA", referencedColumnName "IDA", nullable = false, insertable = false, updatable = false)


par
@MapsId("aIda")
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de marwen109
marwen109 64 Messages postés jeudi 12 août 2010Date d'inscription 26 mars 2012 Dernière intervention - 25 mars 2012 à 20:30
0
Utile
pas de réponse
Commenter la réponse de marwen109
cs_Julien39 6450 Messages postés mardi 8 mars 2005Date d'inscription 17 mai 2018 Dernière intervention - 26 mars 2012 à 08:15
0
Utile
Bonjour,

Tu essayes d'insérer dans la table B un ligne de données qui fait référence à la table A et l'enregistrement n'est pas encore ajouté dans la table A.

Il faut d'abord ajouter l'id dans la table A avant de l'ajouter dans la table B.
Commenter la réponse de cs_Julien39
marwen109 64 Messages postés jeudi 12 août 2010Date d'inscription 26 mars 2012 Dernière intervention - 26 mars 2012 à 14:40
0
Utile
Merci Julien pour la réponse,
voici une nouvelle version plus propre :

...
public class A implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name "IDA", nullable false)
private Integer ida;
@Basic(optional = false)
@Column(name "NAME", nullable false, length = 30)
private String name;
@OneToMany(cascade CascadeType.ALL, mappedBy "a")
private List bList=new ArrayList();

public void addB(B bp){
bp.setA(this);
bList.add(bp);
}
...


B.java:
...
public class B implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected BPK bPK;
@Basic(optional = false)
@Column(name "NAME", nullable false, length = 30)
private String name;
@JoinColumn(name "A_IDA", referencedColumnName "IDA", nullable = false, insertable = false, updatable = false)
@ManyToOne(optional = false)
private A a;
...


le code de la class main:
  A a=new A(null,"A1");
   BPK bpk=new BPK();
   bpk.setIdb("b1");
   a.addB(new B(bpk,"B1"));

   EntityManager em=getEntityManager();
   em.getTransaction().begin();
   em.persist(a);
   em.getTransaction().commit();
Commenter la réponse de marwen109
marwen109 64 Messages postés jeudi 12 août 2010Date d'inscription 26 mars 2012 Dernière intervention - 26 mars 2012 à 14:51
0
Utile
Il faut d'abord ajouter l'id dans la table A avant de l'ajouter dans la table B.


oui je sait , il ya un problème de contrainte d’intégrité référentielle, mais il ne faut pas oublier que je travail avec JPA comme ORM , normalement il se charge lui même de trier l'ordre d'insertion...
j'ai déja travaillé avec une relation 1..N avec ce code SQL et ça marche :
CREATE TABLE parent (
  idparent INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(30) NOT NULL,
  PRIMARY KEY(idparent)
);

CREATE TABLE child (
  idchild INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  parent_idparent INTEGER UNSIGNED NOT NULL,
  name VARCHAR(30) NOT NULL,
  PRIMARY KEY(idchild),
  FOREIGN KEY(parent_idparent)
    REFERENCES parent(idparent)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION
);




lorsque je fait em.persist(parent) l'objet parent est inserée dans la BD avec tous ces Childs automatiquement(cascade), il suffit d'indiquer a l'objet parent qu'il est "lié" a une liste des Childs...

le problème peut-être viens du fait que j'utilise un clé composite(BPK) , je suis complètement bloquée...
Commenter la réponse de marwen109

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.