首页 > 解决方案 > 当类删除对关联表的引用时,如何从关联表中删除行?

问题描述

我有三个类,用户和产品,以及它们的关联类订单。我希望能够通过在 User 或 Product 中编辑 Set 来添加和删除关联表中的行。添加工作正常,但是当我从例如用户中删除一些订单时,它们会保存在数据库中。

按照这个例子,我想出了这段代码。

@Getter
@Setter
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Set<Order> orders;

    public void setOrders(Set<Order> orders) {
        this.orders = orders;
        orders.forEach(order -> order.setUser(this));
    }
}

@Getter
@Setter
@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
    private Set<Order> orders;

    public void setOrders(Set<Order> orders) {
        this.orders = orders;
        orders.forEach(order -> order.setProduct(this));
    }
}

和关联类:

@Getter
@Setter
@Entity
@NoArgsConstructor
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @ManyToOne
    @JoinColumn
    private Product product;

    @NotNull
    @ManyToOne
    @JoinColumn
    private User user;

    public Order(User user, Product product) {
        this.user = user;
        this.project = project;
    }

    @Override
    public boolean equals(Object o){
        if (this == o) return true;
        if (!(o instanceof Order)) return false;
        Engagement that = (Order) o;
        return Objects.equals(user.getUsername(), 
                           that.user.getUsername()) &&
               Objects.equals(product.getName(), 
                           that.product.getName());
    }

    @Override
    public int hashCode(){
        return Objects.hash(user.getUsername(), 
                           product.getName());
    }
}

在我的 OrderService 类中,我添加和编辑一组订单,如下所示:

public addProductsToUser(User user, Set<Product> products){
    Set<Order> orders = products.stream().map(product -> new Order(user, product)).collect(Collectors.toSet());
    user.setOrders(orders);
    userRepository.save(user); //save from CrudRepository
}

我希望当我更新用户时它也会更新订单,以便不再引用的订单将被删除,但我得到了多个订单条目。

标签: javamysqlspringhibernatejpa

解决方案


我想你正在寻找orphanRemoval = true. 这指定了与父对象断开连接的对象将被删除。

在您的情况下,注释看起来像这样:

@OneToMany(mappedBy = "user", orphanRemoval = true, cascade = CascadeType.ALL)
private Set<Order> orders;

有关更多详细信息以及这两者之间的区别,请参阅这篇文章: 从 DB 中删除级联和孤儿有什么区别?


推荐阅读