While creating an online shop application using play-1.2.4
,I ran into some problems with jpa..I wanted to provide an admin area using the CRUD module
in play.Here ,an admin user can create/edit or delete the entities in the application(like Customer
s,Order
s,Item
s etc).
A Customer
can create Orders.Each Order
will have a Set of CartItem
s.When an Order
is deleted,the corresponding CartItem
s must be deleted.When a Customer
is deleted,all his Orders must be deleted as well.I thought I could get this by setting the cascade
property in jpa annotation.
I modelled it like this
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;
...
}
The following database tables were created
customer table
id | email | fullname | currentpayment_id
---|-------------|---------------|-----------------
2 |jon@gmail.com| jon |29
order table
id |customer_id | paymentmethod_id
----+------------+-----------------
25 | 2 | 29
cartitem table
id | quantity | item_id
----+----------+---------
26 | 1 | 14
*order_cartitem table*
order_id | cartitems_id
----------+--------------
25 | 26
In the Admin interface created using CRUD(I haven't implented any methods ,just using the provided CRUD module as is),I tried to delete a Customer,but then,I get this error,
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
Is there something wrong with the way I modelled the Entities? I thought the delete on the Customer
will be cascaded to Order
and that in turn will cascade to its CartItem
s .
What do I have to do to get this cascading effect?Or do I have to manually remove each contained instances of CartItem
s?
EDIT: As per Seb's reply
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();
...
}
This gets rid of order_cartitem table and adds a field order_id to cartitem table
cartitem table
id | quantity | item_id | order_id
----+----------+---------+----------
26 | 1 | 14 | 25
27 | 1 | 20 | 25
The admin(CRUD)
interface,lists the Customer
s and Order
s.When a particular Customer
(the one who created the Order
) is selected and the delete button is clicked,it results in a JPA error
JPA error
A JPA error occurred (Cannot commit): collection owner not associated with session: models.Order.cartItems
here is the stacktrace
If someone can understand why this is happening,please tell me.
Interestingly,I can click on the delete button
for a particular Order
,and it successfully calls the following controller method,
Admin.java
public static void deleteOrder(Long id) {
Order order = Order.findById(id);
order.delete();
...
}
which deletes the Order
and all its CartItem
s successfully..
So,why does this not happen when a Customer
is deleted?