【问题标题】:Spring Data Jpa delete foreign key rows on delete mapping?Spring Data Jpa在删除映射上删除外键行?
【发布时间】:2019-01-10 20:15:49
【问题描述】:

这是我的第一个实体。

@Entity
@Table(name = "person")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;    

    private String firstName;
    private String lastName;

    // Removed other stuff for brevity
}

这是我的第二个实体

@Entity
@Table(name = "membership")
public class Membership {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String membershipType;

    // Help here, I need another column called person_id which is what will correspond 
    // to persons or person rows from person table
}

基本上在person 表中,我们将有n 人(n 行)。而在membership 表中,每个人我们可以有 3-4 列(取决于他们的membershipType,因为每个人都可以拥有多个成员资格,如主要、组、个人、次要等,请原谅业务逻辑)。所以实际上membership 表可能有超过n 行。

现在我有几个问题

  1. 这是来自person -> membership 表的OneToMany 还是ManyToOne?我从person -> membership table 猜测它的OneToMany

  2. 如何在我的 jpa 注释和实体类中实现这种映射?我需要这个用于删除操作,即,如果我删除 membership row,则不应删除相应的 person row。但是,如果我删除person rowALL 对应的membership rows 应该被删除。我如何去实现这个映射和功能?

【问题讨论】:

    标签: hibernate jpa spring-data-jpa one-to-many cascading-deletes


    【解决方案1】:

    Person(不是person.id)添加到您的Membership

    @ManyToOne
    private Person person;
    

    这将被大致理解为“许多会员资格可以属于一个人”。如果您删除一个或多个Membership,则不会删除Person;它只是不会再删除会员资格了。

    为了删除一个Person 中的所有Memberships - 当Person 被删除时 - 将成员列表添加到Person

    @OneToMany(cascade = CascadeType.ALL, mappedBy="person") // maybe CascadeType.REMOVE is enough for you
    private List<Membership> memberships = new ArrayList<>();
    

    实际上,如果没有它,您将无法删除任何Person,然后再删除其所有Memberships;后者对Person 有一个外键约束。

    这将被大致理解为'一个人可以拥有多个成员'。如果你删除Person,它的所有Memberships也将被删除。

    需要列表,因为这样 JPA 可以将删除级联到 Membership,因为存在 CascadeType.ALL(或删除)。

    mappedBy 属性告诉 JPA 检查要映射到的字段 person。如果 JPA 无法找到要映射的字段,它将创建一个单独的表进行映射。

    【讨论】:

    • 1.在Membership 表中这会创建一个名为person 的列吗? 2. 声明List&lt;Memberships&gt; memberships时是否应该做new ArrayList&lt;&gt;();
    • @theprogrammer 1. 将参照表personid 创建一个名为person_id 的列。 2. 这是一种方式。但它也可以在将第一个Membership 添加到Person 之前初始化。 EntityManager 在需要时会自动初始化它,但如果是null,当然不能添加任何Membership
    • 哦,好的,谢谢。最后一个疑问。在您提供的@OneToMany 代码中,它还会在Person 表中创建一个新列吗?如果是这样,它的列名称是什么?
    • @theprogrammer 不,它没有。此列表纯粹是在 Java 方面。如果有某个列,它只能引用一个Membership,对吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多