【问题标题】:Remove parent when child is removed cascade type移除子级时移除父级
【发布时间】:2019-12-15 23:50:42
【问题描述】:

我无法弄清楚级联类型的概念。假设我有两个类,用户和订单。一些用户可能有订单,所以我在订单中引用了用户。

用户:

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String firstName;
    private String lastName;
    private String phone;
    private String email;
}

订单:

@Entity
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @OneToOne
    private User owner;
    private int price;
}

我希望在删除相应用户时删除订单。该怎么做?

【问题讨论】:

    标签: mysql database hibernate jpa cascade


    【解决方案1】:

    级联操作的解释在底部。

    您的问题标题“删除子级联类型时删除父级”。不建议在删除子项时也删除父项。但是如果你想拥有它,你应该修改 Order 实体(单向关系,因为在 User 实体中没有订单引用)。

    @Entity public class Order {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @ManyToOne(cascade = CascadeType.ALL) 
    or when only cascading for the removal @ManyToOne(cascade=CascadeType.REMOVE) 
    @JoinColumn(name = "USER_ID")
    private User owner;
    private int price;
    

    更好的是改变实体。一些用户可能有订单。所以我会向用户添加注释@OneToMany。

       @Entity
        public class User {
    
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            private Long id;
            private String firstName;
            private String lastName;
            private String phone;
            private String email;
            @OneToMany(cascade = CascadeType.ALL)
            @JoinColumn(name = "USER_ID")
            private List<Order> orders
        }
    
    @Entity
    public class Order {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private int price;
    }
    

    当 Order 实体(以上代码)中没有对 User 的引用时,称为单向关系。您可以在 Order 中添加一个引用,使关系成为双向的。

    典型的双向关系示例:

    @Entity
    public class User {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String firstName;
        private String lastName;
        private String phone;
        private String email;
        @OneToMany(cascade = CascadeType.ALL, mappedBy="owner");
        private List<Orders> orders
    }
    
    @Entity
    public class Order {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        @ManyToOne
        @JoinColumn(name = "USER_ID")
        private User owner;
        private int price;
    }
    

    在 User @OneToMany 关系上级联 CascadeType.ALL 意味着对 User 实体的所有操作都将传播到 Order 实体。因此,当删除用户时,属性列表“订单”的所有订单也将被删除。您可以定义一些 CascadeTypes。例如,当您删除用户时只有 CascadeType.REMOVE 时,它的订单列表也将被删除,但是当您保存用户时,订单将不会被保存。在大多数情况下,CascadeType.ALL 很受欢迎,并建议在关系的 @OneToMany 方面。

    如果您需要阅读有关级联数据库操作的更多信息,请点击以下链接: https://www.baeldung.com/jpa-cascade-types.

    对于双向方法,如果我希望每个用户只有一个订单怎么办?

    最简单的方法是将@OneToMany、@ManyToOne 两边都改成@OneToOne。 @OneToOne 关系的默认可选属性为 true,这意味着用户不需要有订单。 其他解决方案可能是使用 @MapsId 注释。还有其他的。最好的方法取决于一些标准,比如你必须有一个双向关系还是单向就足够了,如果两个实体都必须在关系中设置,如果你想延迟加载 @OneToOne。

    【讨论】:

    • 对于双向方式,如果我只想为每个用户一个订单怎么办?
    猜你喜欢
    • 1970-01-01
    • 2013-09-15
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多