14

我只是想知道是否有这样一种方法可以构建我的 MySQL 表

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

<property name="hibernate.hbm2ddl.auto" value="create" />但是,只有当 hibernate ++ jpa 开始构建具有“ ”的表时,我才在我的 DDL 中得到了这个

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)中删除一条记录,这也将允许我根据父/主表中的特定记录级联删除到子记录。

谢谢!

4

4 回答 4

14

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

@OneToMany(cascade=CascadeType.REMOVE)

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

@OnDelete(action = OnDeleteAction.CASCADE)

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

于 2013-02-14T18:50:19.327 回答
9

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

链接显示如何在 MySQL中使用ON DELETE CASCADEon 。CONSTRAINT您在约束上执行此操作。您也可以在CREATE TABLEorALTER TABLE语句中执行此操作。JPA 很可能在ALTER TABLE语句中创建了约束。只需添加ON DELETE CASCADE到该声明。

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

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

于 2013-10-31T01:26:23.457 回答
4

org.hibernate.annotations@OnDelete(action = OnDeleteAction.CASCADE)您可以在以下位置使用 Hibernate 注释UserAcc.userInfo

public class UserAcc implements Serializable {

...

@OneToOne(mappedBy = "userAcc")
@OnDelete(action = OnDeleteAction.CASCADE)
private UserInfo userInfo;

...

这将在表中ON DELETE CASCADE的外键上生成 DDL 。UserInfo

于 2017-04-21T13:32:01.650 回答
0

您可以使用@JoinColumn( foreignKey = @ForeignKey(...)) 手动定义约束,如下所示:-

// 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 = @ForeignKey(
                name="FK_USER_ID",
                foreignKeyDefinition = "FOREIGN KEY (USERID) REFERENCES USERACCOUNT(USERID) ON UPDATE CASCADE ON DELETE CASCADE"
        )
)
private UserAcc userAcc;


public Integer getUserInfoId() {
    return userInfoId;
}

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

这将在生成 DDL 期间添加约束。

生成过程完成后,你可以查看USERINFO表的DDL,你会发现约束已经添加了级联动作,如下所示:-

create table USERINFO(
    ....,
    ....,
    ....,
    ....,
    constraint FK_USER_ID foreign key (USERID) references USERACCOUNT(USERID) on update cascade on delete cascade
);
于 2021-03-09T01:25:04.403 回答