web-dev-qa-db-fra.com

Exception JPA épargnant parent/enfants

J'utilise JPA et possède les éléments suivants:

ProductEntity 

@Basic
@Column(name = "PRODUCT_ID", nullable = false, length = 128)
private String productId;

@ManyToOne
@JoinColumn(name = "PARENT_ID")
private ProductEntity parent;

Comme vous pouvez le voir, la table des produits peut avoir un parent. Effectivement une relation parent-enfant.

J'ai un produit enregistré dans la base de données, puis j'ajoute des produits enfants, chacun ayant le même parent.

  • Le produit parent a ProductEntity parent = null; 
  • Les produits enfants ont ProductEntity parent = le produit parent;

    ProductEntity parentProductEntity = ...
    ProductEntity childProductEntity1 = ...
    ProductEntity childProductEntity2 = ...
    
    em.persist(parentProductEntity);
    childProductEntity1.setParent(parentProductEntity);
    childProductEntity2.setParent(parentProductEntity);
    em.merge(childProductEntity1);
    

Données (il n'insère jamais les deux dernières lignes enfants)

    ID        PRODUCT_ID     PARENT_ID
     1           1              null
     2           2                1
     3           3                1

Problème

J'essaie ensuite de sauver chaque produit enfant. Mais j'obtiens une erreur indiquant qu'il y a une clé en double (productId). Lors de la sauvegarde de l'enfant, il tente également de sauvegarder une entrée dupliquée du parent.

Causée par: org.postgresql.util.PSQLException: ERROR: clé en double valeur viole la contrainte unique "t_osm_product_product_id_uindex"

Question

Comment dois-je changer ce que je fais pour sauver chaque produit enfant?

Merci

7
Richard

votre entité devrait ressembler à ceci 

@Id
Long ID;

@Column(name = "PRODUCT_ID", nullable = false, length = 128)
private String productId;

@ManyToOne
@JoinColumn(name = "PARENT_ID")
private ProductEntity parent;

tout le reste semble bien dans votre code.

Les données ressembleront à ceci dans la base de données

 ID        PRODUCT_ID     PARENT_ID
 1           abc              null
 2           def                1
 3           xyz                1
2
Reza Nasiri

Veuillez changer le point suivant et vérifier: - 

  • Utilisez "persister" à la place "fusionner" et faites comme suit. 

{

public static void main (String[] agrs){
EntityManager em = ... // from EntityManagerFactory, injection, etc.

em.getTransaction().begin();

A parent   = new A();
A son      = new A();
A daughter = new A();

son.setParent(parent);
daughter.setParent(parent);

em.persist(parent);
em.persist(son);
em.persist(daughter);

em.getTransaction().commit();
}
0
Parkash

Vous pouvez essayer @ManyToOne(cascade=CascadeType.MERGE)

0
Sahin Yanlık