gpt4 book ai didi

java - playframework 中的级联删除 - 如何为实体建模

转载 作者:搜寻专家 更新时间:2023-10-31 20:30:09 25 4
gpt4 key购买 nike

使用 play-1.2.4 创建在线商店应用程序时,我在使用 jpa 时遇到了一些问题。我想使用 CRUD module 提供一个管理区域在 play.Here 中,管理员用户可以创建/编辑或删除应用程序中的实体(如 Customer s、Order s、Item s 等​​)。

A Customer可以创建 Orders.Each Order将有一组 CartItem s.当一个Order被删除,对应的CartItem s 必须被删除。当一个 Customer被删除,他的所有订单也必须被删除。我想我可以通过设置 cascade 来得到这个jpa 注释中的属性。

我是这样设计的

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

创建了以下数据库表

客户表

id |  email      |   fullname    | currentpayment_id
---|-------------|---------------|-----------------
2 |jon@gmail.com| jon |29

订单表

 id |customer_id | paymentmethod_id 
----+------------+-----------------
25 | 2 | 29

cartitem 表

id  | quantity | item_id 
----+----------+---------
26 | 1 | 14

*order_cartitem 表*

 order_id | cartitems_id 
----------+--------------
25 | 26

在使用 CRUD 创建的管理界面中(我没有实现任何方法,只是按原样使用提供的 CRUD 模块),我试图删除一个客户,但是,我得到这个错误,

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

我对实体建模的方式有问题吗?我以为删除了 Customer将级联到Order而这又会级联到它的CartItem .

我必须做什么才能获得这种级联效果?或者我必须手动删除每个包含的 CartItem 实例吗?是吗?

编辑:根据 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();
...
}

这去掉了 order_cartitem 表并添加了一个字段 order_idcartitem 表

cartitem 表

     id | quantity | item_id | order_id 
----+----------+---------+----------
26 | 1 | 14 | 25
27 | 1 | 20 | 25

admin(CRUD)界面,列出Customer s 和 Order s.当一个特定的Customer (创建 Order 的人)被选中并单击删除按钮,结果是 JPA error

JPA error
A JPA error occurred (Cannot commit): collection owner not associated with session: models.Order.cartItems

这里是 stacktrace

如果有人能理解为什么会这样,请告诉我。

有趣的是,我可以点击delete button对于特定的 Order , 并且成功调用了下面的 Controller 方法,

Admin.java

public static void deleteOrder(Long id) {
Order order = Order.findById(id);
order.delete();
...
}

删除 Order及其所有 CartItem成功了。。那么,为什么在 Customer 时不会发生这种情况?被删除了?

最佳答案

通过将此添加到您的 cartitem 类使您的关系双向

@ManyToOne
public Order order;

还有一个 mappedBy="order"在你的 cartItems @OneToMany

那么 hibernate 将更好地处理您的删除。我猜如果没有这个双向链接,hibernate 会首先尝试将列设置为空。您还可以尝试在连接表中允许空值,看看如果您不想启用双向关系会发生什么

关于java - playframework 中的级联删除 - 如何为实体建模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9561679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com