gpt4 book ai didi

hibernate - 防止删除级联到实体实例

转载 作者:行者123 更新时间:2023-12-02 15:23:19 24 4
gpt4 key购买 nike

考虑以下 JPA 实体:

@Entity @Table(name = "product") class Product { ... }

@Entity @Table(name = "stock") class Stock {
@JoinColumn(name = "product_id", updatable = false)
@ManyToOne(fetch = FetchType.LAZY)
private Product product;

@Column(name = "quantity")
private Long quantity;
}

@Entity @Table(name = "cart") class Cart {
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "cart", orphanRemoval = true)
private List<CartItem> items = new ArrayList<>();

public void addItem(CartItem item) { items.add(item); }
public void removeItem(CartItem item) { items.remove(item); }
}

@Entity @Table(name = "cart_item") class CartItem {
@JoinColumn(name = "cart_id", updatable = false)
@ManyToOne(fetch = FetchType.LAZY)
private Cart cart;

@JoinColumn(name = "product_id", updatable = false)
@ManyToOne(fetch = FetchType.LAZY)
private Product product;

@Column(name = "quantity")
private Long quantity;

@JoinColumn(name = "stock_id", updatable = false)
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Stock stock;

public void setQuantity(Long quantity) {
final Long delta = this.quantity - Math.max(0L, quantity);

this.quantity += delta;
this.stock.setQuantity(this.stock.getQuantity() - delta);

if(quantity < 1) { cart.removeItem(this); }
}
}

注意从 CartItemStock 的关联。此关联已被注释,因此更改购物车商品数量会影响其在另一个方向的可用库存,即,如果购物车商品数量增加,则产品的可用库存数量会减少,反之亦然。

这允许我触发 cartRepository.save(cart),保存所有购物车项目并同时更新它们的库存(由于 Cascade.ALL 来自 CartCartItem)。只要购物车商品的数量不为零,这就可以正常工作。

但是,当在调用 cart.removeItem(item) 之后调用 cartRepository.save(cart) 时,级联也会尝试删除购物车商品的库存,这不是意图。应删除购物车项目,但应仅更新其关联的库存。有没有一种方法可以将 CartItem 的更新级联到 Stock 但将 CartItem 上的级联删除作为 Stock 上的更新进行级联删除?

最佳答案

改变

class CartItem {
@JoinColumn(name = "stock_id", updatable = false)
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Stock stock;
}

class CartItem {
@JoinColumn(name = "stock_id", updatable = false)
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch = FetchType.LAZY)
private Stock stock;
}

(CascadeType.ALL to { CascadeType.MERGE, CascadeType.PERSIST }) 解决了这个问题。以前调用 cartItem.setQuantity(0) 时会执行以下 SQL 查询:

delete from cart_item where id=?
delete from stock where id=?

随着更改,将根据需要执行以下 SQL 查询:

update stock set quantity=? where id=?
delete from cart_item where id=?

示例应用程序是 available on Github用于检查解决方案的正确性。

关于hibernate - 防止删除级联到实体实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33412817/

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