2013-03-17 4 views
5

J'ai une relation un-à-plusieurs: Une catégorie de produits peut contenir plusieurs produits. Voici le code:JPA Cascade Persist Error

@Entity 
public class Product implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private String id; 
    @Column(name="ProductName") 
    private String name; 
    private BigDecimal price; 
    private String description; 
    @ManyToOne 
    @JoinColumn(name="UserId") 
    private User user; 
    @ManyToOne 
    @JoinColumn(name="Category") 
    private ProductCategory category; 
    private static final long serialVersionUID = 1L; 

    public Product() { 
     super(); 
    } 
    public String getId() { 
     return this.id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 
    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
    public BigDecimal getPrice() { 
     return this.price; 
    } 

    public void setPrice(BigDecimal price) { 
     this.price = price; 
    } 
    public String getDescription() { 
     return this.description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 
    public User getUser() { 
     return this.user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 
    public ProductCategory getCategory() { 
     return this.category; 
    } 

    public void setCategory(ProductCategory category) { 
     this.category = category; 
    } 
} 


@Entity 
public class ProductCategory { 
    @Id 
    private String categoryName; 
    @OneToMany(cascade= CascadeType.ALL,mappedBy="category") 
    private List<Product> products; 

    public String getCategoryName() { 
     return categoryName; 
    } 

    public void setCategoryName(String productName) { 
     this.categoryName = productName; 
    } 

    public List<Product> getProducts() { 
     return products; 
    } 

    public void setProducts(List<Product> products) { 
     this.products = products; 
    } 

} 

Ce code est Servlet qui utilisent les 2 entités:

String name = request.getParameter("name"); 
BigDecimal price = new BigDecimal(request.getParameter("price")); 
String description = request.getParameter("description"); 
ProductCategory category = new ProductCategory(); 
category.setCategoryName(request.getParameter("category")); 
Product product = new Product(); 
product.setName(name); 
product.setPrice(price); 
product.setDescription(description); 
product.setCategory(category); 
User user = userManager.findUser("Meow"); 
product.setUser(user); 
productManager.createProduct(product); // productManager is an EJB injected by container 

Et voici l'erreur:

java.lang.IllegalStateException: Lors de la synchronisation d'une nouvelle objet a été trouvé par une relation qui n'a pas été marqué cascade PERSIST

Pourquoi cette erreur se produise? J'ai marqué le champ comme "cascade = CascadeType.All"!

Répondre

10

Vous essayez d'enregistrer un produit. Et ce produit est lié à une catégorie. Ainsi, lorsque JPA enregistre le produit, sa catégorie doit déjà exister, ou une cascade doit être configurée pour que la persistance du produit entraîne la persistance de sa catégorie.

Mais vous n'avez pas une telle cascade. Ce que vous avez est une cascade disant que toute opération effectuée sur une catégorie cascades à sa liste de produits.

+0

alors que dois-je faire? Si je change le code à: @OneToMany (cascade = CascadeType.PERSIST, mappedBy = "catégorie") privé Liste produits; cela ne fonctionne pas non plus. Cela donne la même erreur. –

+4

La cascade est du mauvais côté de l'association. Vous dites à JPA: * quand je vous demande de persister dans une catégorie, persiste aussi ses produits *. Mais vous ne demandez pas à JPA de persister dans une catégorie. Vous lui demandez de persister un produit. Et nulle part avez-vous dit que lorsqu'un produit est persistant, sa catégorie doit également être conservée. –

+0

alors de quel côté pensez-vous que la notation en cascade devrait être? Aussi longtemps que je le sais, dans une relation de type «un à un», c'est toujours à l'inverse (c'est-à-dire le côté ou par un autre, le côté qui contient l'annotation @OneToMany). –

Questions connexes