如何在一对多关系中删除一个实体?

后端开发 2026-07-11

我在实现一个小型电子商务系统,但遇到了如下问题:无法删除具有一对多关系的实体。

我有一个购物车类,定义如下:

@Entity
@Table(name = "cart")
public class Cart extends NameEntity {

    @OneToMany(mappedBy = "cart",cascade = {CascadeType.ALL},orphanRemoval = true)
    private List<Item> items = new ArrayList<>();

    public void addItem(Item item) {
        item.setCart(this);
        this.items.add(item);
    }

    public BigDecimal getTotal() {
        if (items.isEmpty())
            return BigDecimal.ZERO;
        double total = 0;
        for (Item item : items) {
            total += item.getCount() *
                    item.getProduct().getPrice().doubleValue();
        }
        return BigDecimal.valueOf(total);
    }


    public Item get(Integer id) {
        for (Item item : items) {
            if (Objects.equals(item.getId(), id))
                return item;
        }
        throw new NoSuchElementException("暂未找到钙元素");
    }

    public void removeItem(Item item) {
        this.items.remove(item);
    }

我还拥有一个Item实体,表示购物车中的商品数据:

@Entity
@Table(name = "buy_item")
public class Item extends IDEntity {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "cart_id",nullable = false) 
    private Cart cart;


    @OneToOne(fetch = FetchType.LAZY,optional = false) 
    @JoinColumn(name = "product_id",unique = true) 
    private Product product;

    private int count;

    @CreationTimestamp
    @Column(name = "order_time")
    private LocalDateTime orderTime;
}

我主要想实现购物车购买的逻辑。

以下是我的购物车购买逻辑:

 @PostMapping("/buy/{id}")
    public String pay(@PathVariable("id") Integer itemId,
                      @SessionAttribute(name = "user") User user)
    {

        User u = userRepo.findById(user.getId()).orElseThrow();
        Item item = itemRepo.findById(itemId).orElseThrow();
        Cart cart = u.getCart();
        cart.removeItem(item);
        OrderInfo orderInfo = itemToOrderInfo(item);
        Order order = new Order();
        order.setState(OrderState.PACKING);
        order.setShippingAddress(u.getProfile().getAddress());
        order.addOrderInfo(orderInfo);
        u.addOrder(order);
        orderRepo.save(order);

        cartRepo.save(cart);
        return "redirect:/order/list";
    }

当我点击购买时,会向这个接口发送请求。我的期望是:

  1. 获取用户的购物车;

  2. 删除购物车中已购买的商品;

  3. 生成一个订单;

  4. 保存订单;

  5. 保存购物车。

然而,我发现购物车中的商品仍然存在。我接下来该怎么尝试?

解决方案

问题在于你只是把该项从购物车的列表中移除了,但Item本身在数据库中仍然指向该购物车。在JPA中,关系的多的一方(Item)控制着关系。要删除它,必须同时断开双方的链接。
Cart 类中,更新它的 removeItem 方法:

public void removeItem(Item item) {
    this.items.remove(item);
    item.setCart(null); // This triggers the orphanRemoval
}

之所以这样,是因为你有 orphanRemoval = true,设置 item.setCart(null) 会告诉Hibernate这个项不再有父对象。Hibernate将自动从数据库中删除该行。若没有那一行,数据库仍然会看到 cart_id,并使该项继续存在。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章