2013-03-17 32 views
5

Mam relację jeden do wielu: kategoria produktów może zawierać wiele produktów. Jest to kod:Błąd kaskady JPA

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

} 

Jest to kod serwletów, które używać 2 podmioty:

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 

i to jest błąd:

java.lang.IllegalStateException: Podczas synchronizacji nowego obiekt został znaleziony przez relację, która nie została oznaczona kaskadą PERSIST

Dlaczego ten błąd się wydarzył? Oznaczono to pole jako "cascade = CascadeType.All"!

Odpowiedz

10

Próbujesz zapisać produkt. Ten produkt jest powiązany z kategorią. Tak więc, gdy JPA zapisuje produkt, jego kategoria musi już istnieć lub musi istnieć kaskada skonfigurowana tak, aby utrzymywać kaskadę produktu, aby utrzymać swoją kategorię.

Ale nie masz takiej kaskady. To, co masz, to kaskada mówiąca, że ​​jakakolwiek operacja wykonana w danej kategorii przechodzi kaskadowo na jej listę produktów.

+0

więc co mam zrobić? Jeśli zmienię kod na: @OneToMany (cascade = CascadeType.PERSIST, mappedBy = "category") private List produktów; to też nie działa. Daje ten sam błąd. –

+4

Kaskada znajduje się po niewłaściwej stronie skojarzenia. Mówisz WZP: * kiedy proszę, abyś utrzymywał kategorię, także utrzymuj jej produkty *. Ale nie prosisz JPA o utrzymywanie kategorii. Prosisz go, aby utrzymywał produkt. I nigdzie nie powiedziałeś, że gdy produkt będzie się utrzymywał, jego kategoria również musi być utrzymywana. –

+0

, po której stronie, twoim zdaniem, powinna być włączona notacja kaskadowa? Tak długo, jak wiem, w relacji "wiele do jednego", zawsze jest po stronie odwrotnej (czyli jednostronnie lub przez inne powiedzenie, strona zawierająca adnotację @OneToMany). –