2013-03-17 12 views
5

Ich habe eine Eins-zu-viele Beziehung: Eine ProductCategory kann viele Produkte enthalten. Dies ist der Code:JPA Cascade Persist Fehler

@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; 
    } 

} 

Dies ist Servlet-Code, der die 2 Einheiten verwenden:

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 

und das ist der Fehler:

java.lang.IllegalStateException: Während der Synchronisation eines neuen Objekt wurde über eine Beziehung gefunden, die nicht als Kaskade markiert wurde. PERSIST

Warum tritt dieser Fehler auf? Ich habe das Feld als "cascade = CascadeType.All" markiert!

Antwort

10

Sie versuchen, ein Produkt zu speichern. Und dieses Produkt ist mit einer Kategorie verknüpft. Wenn also JPA das Produkt speichert, muss seine Kategorie bereits vorhanden sein, oder es muss eine Kaskade konfiguriert sein, damit die Produktkaskaden beibehalten werden, um ihre Kategorie beizubehalten.

Aber Sie haben keine solche Kaskade. Was Sie haben, ist eine Kaskade, die besagt, dass jede Operation, die in einer Kategorie ausgeführt wird, zu ihrer Produktliste kaskadiert.

+0

Was soll ich tun? Wenn ich den Code ändern: @OneToMany (cascade = CascadeType.PERSIST, mappedBy = "category") private Liste Produkte; funktioniert es auch nicht. Es gibt denselben Fehler. –

+4

Die Kaskade befindet sich auf der falschen Seite der Assoziation. Du sagst JPA: * wenn ich dich auffordere, eine Kategorie beizubehalten, behalte auch ihre Produkte * bei. Aber Sie fordern JPA nicht auf, eine Kategorie beizubehalten. Sie bitten darum, ein Produkt zu erhalten. Und nirgendwo haben Sie gesagt, dass wenn ein Produkt dauerhaft ist, seine Kategorie auch beibehalten werden muss. –

+0

also auf welcher Seite denkst du, dass die Kaskadenschreibweise eingeschaltet sein sollte? Solange ich weiß, ist es in einer Many-To-One-Beziehung immer auf der inversen Seite (bedeutet die eine Seite oder die andere Seite, die Seite, die die Annotation @ OneToMany enthält). –