JPA + 休眠:如何定义具有 ON DELETE 级联的约束

2022-09-03 12:24:46

我只是想知道是否有这样一种方法可以让我的MySQL表作为

ALTER TABLE `USERINFO`
  ADD CONSTRAINT `FK_USER_ID` FOREIGN KEY (`USERID`) REFERENCES `USERACCOUNT` (`USERID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE;

但是,只有当休眠 ++ jpa 开始构建具有 ”<property name="hibernate.hbm2ddl.auto" value="create" />"

ALTER TABLE `USERINFO` ADD CONSTRAINT `FK_USER_ID` FOREIGN KEY (`USERID`) REFERENCES `USERACCOUNT` (`USERID`);

在我的课堂上,我有这些注释设置,

// UserAcc.java
@Entity
@Table(name = "USERACC")
public class UserAcc implements Serializable {

private static final long serialVersionUID = -5527566248002296042L;

@Id
@Column(name = "USERID")
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer userId;


@OneToOne(mappedBy = "userAcc")
private UserInfo userInfo;
....


public UserInfo getUserInfo() {
    return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
    this.userInfo = userInfo;
}
...

// UserInfo.java
@Entity
@Table(name = "USERINFO")
public class UserInfo implements Serializable {

private static final long serialVersionUID = 5924361831551833717L;

@Id
@Column(name = "USERINFO_ID", nullable=false)
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer userInfoId;

@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name="USERID", nullable=false)
@ForeignKey(name = "FK_USER_ID")
private UserAcc userAcc;


public Integer getUserInfoId() {
    return userInfoId;
}

public void setUserInfoId(Integer userInfoId) {
    this.userInfoId = userInfoId;
}
...

请注意,UserAccount 表是此处的父表/主表,而 UserInfo 是规范化为另一个实体的扩展表。任何答案将不胜感激。我只是好奇它是如何完成的,因为我也喜欢在MySQL中工作。我只是非常习惯于从父表(USERACOUNT)中删除记录,这也将允许我根据父表/主表中的特定记录级联删除子记录。

谢谢!


答案 1

JPA 确实提供了将操作(合并、持久化、刷新、删除)级联到关联实体的可能性。逻辑在 JPA 中,不利用数据库级联。

@OneToMany(cascade=CascadeType.REMOVE)

没有符合 JPA 标准的方法来执行与数据库级联的级联。如果首选这样的级联,我们必须回退到Hibernate特定的构造:@OnDelete。它至少适用于,但过去曾存在一些问题,并且。@OneToMany@OneToOne@OnDelete

@OnDelete(action = OnDeleteAction.CASCADE)

请注意,将此批注添加到现有约束不会更新它。您可能需要先手动删除它才能正确更新架构。


答案 2

在JPA中没有干净的切割方法可以做到这一点。以下内容将为您提供所需的内容...可以使用 ,但是此注释仅适用于 中的对象,而不适用于数据库中的对象。您希望确保将其添加到数据库约束中。要进行验证,可以将 JPA 配置为生成 ddl 文件。看一下文件,你会发现这不是约束的一部分。添加到文件中的实际 SQL,然后从 ddl 更新数据库架构。这将解决您的问题。CascadeType.DELETEEntityManagerON DELETE CASCADEddlON DELETE CASCADEON DELETE CASCADEddl

链接显示了如何在 MySQL 中使用 on 。在约束上执行此操作。您也可以在 or 语句中执行此操作。JPA 很可能在语句中创建约束。只需添加该语句即可。ON DELETE CASCADECONSTRAINTCREATE TABLEALTER TABLEALTER TABLEON DELETE CASCADE

请注意,某些 JPA 实现器确实为此功能提供了一种方法。

最后,Hibernate确实使用注释提供了此功能。OnDelete(action = OnDeleteAction.CASCADE)


推荐