【问题标题】:Way to remove row from association table when class removes reference to it?当类删除对关联表的引用时,如何从关联表中删除行?
【发布时间】:2019-09-02 03:25:53
【问题描述】:

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

this example 之后,我想出了这段代码。

@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
}

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

【问题讨论】:

    标签: java mysql spring hibernate jpa


    【解决方案1】:

    我认为您正在寻找orphanRemoval = true。这指定,与父对象断开连接的对象将被删除。

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

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

    有关更多详细信息以及两者之间的区别,请参阅此帖子: What is the difference between cascade and orphan removal from DB?

    【讨论】:

    • 这就是我所缺少的。谢谢你。我遇到了休眠异常:'拥有实体实例不再引用具有 cascade="all-delete-orphan" 的集合',但对this 的第二条评论解决了它。
    猜你喜欢
    • 1970-01-01
    • 2020-11-23
    • 2011-10-12
    • 2012-03-05
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多