java JPA + Hibernate:如何定义具有 ON DELETE CASCADE 的约束
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14875793/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA + Hibernate: How to define a constraint having ON DELETE CASCADE
提问by toytoy
I am just wondering if there's such a way that I can have build my MySQL table as
我只是想知道是否有一种方法可以将我的 MySQL 表构建为
ALTER TABLE `USERINFO`
ADD CONSTRAINT `FK_USER_ID` FOREIGN KEY (`USERID`) REFERENCES `USERACCOUNT` (`USERID`)
ON DELETE CASCADE
ON UPDATE CASCADE;
However, I only got this in my DDL when hibernate ++ jpa starts to build my table having "<property name="hibernate.hbm2ddl.auto" value="create" />
"
但是,当 hibernate ++ jpa 开始构建具有“ <property name="hibernate.hbm2ddl.auto" value="create" />
”的表时,我才在 DDL 中得到了这个
ALTER TABLE `USERINFO` ADD CONSTRAINT `FK_USER_ID` FOREIGN KEY (`USERID`) REFERENCES `USERACCOUNT` (`USERID`);
In my classes, I have these annotation setup,
在我的课程中,我有这些注释设置,
// 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;
}
...
and,
和,
// 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;
}
...
Note that, UserAccount table is the parent/main table here while UserInfo is an extended table normalize to another entity. Any answers would be greatly appreciated. I'm just curious how it's done as I love to work also in MySQL. I am just really used to deleting a record from the parent table (USERACOUNT) which would would also allow me to cascade a delete thru child records dependent on the specific record from a parent/primary table.
请注意,UserAccount 表是此处的父/主表,而 UserInfo 是一个扩展表,将其标准化为另一个实体。任何答案将不胜感激。我只是好奇它是如何完成的,因为我也喜欢在 MySQL 中工作。我只是真的习惯于从父表 (USERACOUNT) 中删除一条记录,这也将允许我通过依赖于父/主表中的特定记录的子记录级联删除。
Thanks!
谢谢!
回答by Mikko Maunu
JPA does offer possibility to cascadeoperations (merge, persist, refresh, remove) to associated entities. Logic is in JPA and does not utilize database cascades.
JPA 确实提供了将操作(合并、持久化、刷新、删除)级联到关联实体的可能性。逻辑在 JPA 中,不使用数据库级联。
@OneToMany(cascade=CascadeType.REMOVE)
There is no JPA standard compliant way to do cascades with database cascades. If such a cascades are preferred, we have to fall back to Hibernate specific construct: @OnDelete. It works with @OneToMany
at least, but there used to be some problems in the past with @OneToOne
and @OnDelete
.
没有符合 JPA 标准的方法来与数据库级联进行级联。如果喜欢这样的级联,我们必须回退到 Hibernate 特定的构造:@OnDelete。它@OneToMany
至少适用于,但过去使用@OneToOne
和 时曾经存在一些问题@OnDelete
。
@OnDelete(action = OnDeleteAction.CASCADE)
Be aware that adding this annotation to an existing constraint will not update it. You may have to manually drop it first to properly update the schema.
请注意,将此注释添加到现有约束不会更新它。您可能必须先手动删除它才能正确更新架构。
回答by cmd
There is no clean cut means to do this in JPA. The following will get you what you want...
You can use CascadeType.DELETE
, however this annotation only applies to the objects in the EntityManager
, not the database. You want to be sure that ON DELETE CASCADE
is added to the database constraint. To verify, you can configure JPA to generate a ddl file. Take a look at the ddl
file, you'll notice that ON DELETE CASCADE
is not part of the constraint. Add ON DELETE CASCADE
to actual SQL in the ddl
file, then update your database schema from the ddl. This will fix your problem .
在 JPA 中没有明确的方法来做到这一点。以下内容将为您提供所需的内容...您可以使用CascadeType.DELETE
,但是此注释仅适用于 中的对象EntityManager
,而不适用于数据库。您要确保将ON DELETE CASCADE
其添加到数据库约束中。要验证,您可以配置 JPA 以生成 ddl 文件。查看ddl
文件,您会注意到它ON DELETE CASCADE
不是约束的一部分。添加ON DELETE CASCADE
到ddl
文件中的实际 SQL ,然后从 ddl 更新您的数据库架构。这将解决您的问题。
This linkshows how to use ON DELETE CASCADE
on for CONSTRAINT
in MySQL. You do this on the constraint. You can also do it in a CREATE TABLE
or ALTER TABLE
statement. It's likely that JPA creates the constraint in an ALTER TABLE
statement. Simply add ON DELETE CASCADE
to that statement.
此链接显示了如何在 MySQL 中使用ON DELETE CASCADE
for CONSTRAINT
。您在约束上执行此操作。您也可以在CREATE TABLE
orALTER TABLE
语句中执行此操作。JPA 很可能在ALTER TABLE
语句中创建了约束。只需添加ON DELETE CASCADE
到该语句中即可。
Note that some JPA implementors do provide a means for this functionality.
请注意,某些 JPA 实现者确实为此功能提供了一种方法。
Lastly, Hibernate does supply this functionality using the OnDelete(action = OnDeleteAction.CASCADE)
annotation.
最后,Hibernate 确实使用OnDelete(action = OnDeleteAction.CASCADE)
注解提供了这个功能。
回答by Alex Torson
You can use Hibernate annotation org.hibernate.annotations@OnDelete(action = OnDeleteAction.CASCADE)
on UserAcc.userInfo
:
您可以使用Hibernate标注org.hibernate.annotations@OnDelete(action = OnDeleteAction.CASCADE)
上UserAcc.userInfo
:
public class UserAcc implements Serializable {
...
@OneToOne(mappedBy = "userAcc")
@OnDelete(action = OnDeleteAction.CASCADE)
private UserInfo userInfo;
...
this will generate DDL ON DELETE CASCADE
on foreign key in UserInfo
table.
这将ON DELETE CASCADE
在UserInfo
表中的外键上生成 DDL 。