Durante la creazione di un'applicazione di negozio online utilizzando play-1.2.4
, ho riscontrato alcuni problemi con jpa..Io volevo fornire un'area di amministrazione utilizzando lo CRUD module
in riproduzione. Qui, un utente amministratore può creare/modificare o eliminare le entità nell'applicazione (come s, Order
s, Item
s ecc.).Eliminazione a catena in file di riproduzione: come modellare le entità
Un Customer
può creare Orders.Each Order
avrà una serie di CartItem
s.When un Order
viene eliminato, i corrispondenti CartItem
s devono essere deleted.When un Customer
viene eliminato, tutti i suoi ordini devono essere eliminati come well.I ho pensato di ottenere questo impostando la proprietà cascade
nell'annotazione jpa.
ho modellato come questo
Customer.java
@Entity
public class Customer extends Model {
@Email
@Required
public String email;
...
@OneToMany(mappedBy="customer", cascade=CascadeType.ALL)
public List<Order> orders;
@OneToOne
public PayMethod currentPayment;
...
}
Order.java
@Entity
public class Order extends Model {
@OneToMany(cascade=CascadeType.ALL,orphanRemoval=true,fetch=FetchType.EAGER)
public Set<CartItem> cartItems;
@ManyToOne
public Customer customer;
@ManyToOne
public PayMethod paymentMethod;
...
}
CartItem.java
@Entity
public class CartItem extends Model implements Comparable<CartItem>{
@ManyToOne
public Item item;
public int quantity;
}
PayMethod.java
@Entity
public class PayMethod extends Model {
@Required
public String cardNumber;
@ManyToOne
public Customer customer;
...
}
Le seguenti tabelle di database sono stati creati
tabella dei clienti
id | email | fullname | currentpayment_id
---|-------------|---------------|-----------------
2 |[email protected]| jon |29
tabella ordine
id |customer_id | paymentmethod_id
----+------------+-----------------
25 | 2 | 29
tabella cartitem
id | quantity | item_id
----+----------+---------
26 | 1 | 14
* tabella order_cartitem *
01.235.164,106 milaorder_id | cartitems_id
----------+--------------
25 | 26
nella interfaccia di amministrazione creati utilizzando CRUD (non ho implented alcun metodo, semplicemente utilizzando il modulo CRUD fornito come è), ho cercato di eliminare un cliente, ma poi, ottengo questo errore,
ERROR: update or delete on table "cartitem" violates foreign key constraint "fk7ff437ad3e28aa91" on table "order_cartitem"
Detail: Key (id)=(26) is still referenced from table "order_cartitem".
08:03:03,031 ERROR ~ Could not synchronize database state with session
C'è qualcosa di sbagliato nel modo in cui ho modellato le Entità? Ho pensato che l'eliminazione sullo Customer
sarà concatenata a Order
e che a sua volta si sovrapporrà ai suoi CartItem
s.
Cosa devo fare per ottenere questo effetto a cascata? O devo rimuovere manualmente ogni istanza contenuta di CartItem
s?
EDIT: Come per la risposta di Seb
class Order extends Model {
@OneToMany(mappedBy="order", cascade=CascadeType.ALL,orphanRemoval=true,fetch=FetchType.EAGER)
public Set<CartItem> cartItems;
...
}
class CartItem extends Model implements Comparable<CartItem>{
@ManyToOne
public Item item;
public int quantity;
@ManyToOne
public Order order;
...
}
static void addItemToCart(Long itemId,Long orderId,String quantity) {
Item item = Item.findById(itemId);
Order order = Order.findById(orderId);
int qty = Integer.parseInt(quantity);
CartItem cartItem = new CartItem(item,qty);
cartItem.order=order;
order.addItem(cartItem, qty);
order.save();
...
}
Questo elimina order_cartitem tavolo e aggiunge un campo order_id al tavolo cartitem
tavolo cartitem
id | quantity | item_id | order_id
----+----------+---------+----------
26 | 1 | 14 | 25
27 | 1 | 20 | 25
L'interfaccia admin(CRUD)
, elenca i Customer
s e Order
s.When un particolare Customer
(colui che ha creato il Order
) è selezionato e il tasto di cancellazione viene cliccato, si traduce in un JPA error
JPA error
A JPA error occurred (Cannot commit): collection owner not associated with session: models.Order.cartItems
qui è il stacktrace
Se qualcuno può capire perché questo sta accadendo, per favore dimmi.
È interessante notare che, posso cliccare sul delete button
per un particolare Order
, e chiama con successo il seguente metodo di controllo,
Admin.java
public static void deleteOrder(Long id) {
Order order = Order.findById(id);
order.delete();
...
}
che elimina la Order
e tutti il suo CartItem
s ha avuto successo .. Quindi, perché questo non accade quando uno Customer
viene cancellato?
Il codice mi sembra a posto. Forse questo thread aiuta un po 'a trovare la causa del problema: http://stackoverflow.com/questions/2011519/jpa-onetomany-not-deleting-child – Bjarne77
grazie per l'ottimo link..si passerà attraverso di esso –