我只是想知道是否有这样一种方法可以将我的MySQL表构建为
ALTER TABLE `USERINFO`
ADD CONSTRAINT `FK_USER_ID` FOREIGN KEY (`USERID`) REFERENCES `USERACCOUNT` (`USERID`)
ON DELETE CASCADE
ON UPDATE CASCADE;
然而,当hibernate ++ 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),这也可以让我通过父/主表的表格依赖于特定记录的子记录级联。
谢谢!
答案 0 :(得分:6)
JPA为关联实体提供cascade操作(合并,保留,刷新,删除)的可能性。逻辑在JPA中,不使用数据库级联。
@OneToMany(cascade=CascadeType.REMOVE)
没有符合JPA标准的方法来进行数据库级联的级联。如果首选这样的级联,我们必须回退到Hibernate特定的构造:@OnDelete。它至少与@OneToMany一起使用,但过去曾经存在@OneToOne和@OnDelete的一些问题。
@OnDelete(action = OnDeleteAction.CASCADE)
答案 1 :(得分:5)
在JPA中没有干净的切割手段。以下将为您提供您想要的...
您可以使用CascadeType.DELETE
,但此注释仅适用于EntityManager
中的对象,而不适用于数据库。您希望确保将ON DELETE CASCADE
添加到数据库约束中。要进行验证,您可以配置JPA以生成ddl文件。看一下ddl
文件,您会注意到ON DELETE CASCADE
不是约束的一部分。将ON DELETE CASCADE
添加到ddl
文件中的实际SQL,然后从ddl更新数据库模式。这将解决您的问题。
此link显示了如何在MySQL中ON DELETE CASCADE
使用CONSTRAINT
。您可以在约束上执行此操作。您也可以在CREATE TABLE
或ALTER TABLE
语句中执行此操作。 JPA可能会在ALTER TABLE
语句中创建约束。只需将ON DELETE CASCADE
添加到该语句中即可。
请注意,某些JPA实现者确实提供了此功能的方法。
最后,Hibernate使用OnDelete(action = OnDeleteAction.CASCADE)
注释提供此功能。
答案 2 :(得分:2)
您可以在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
。
答案 3 :(得分: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
);