在JPA2多对多关系上执行CASCADE DELETE [英] ON CASCADE DELETE on JPA2 many-to-many relationship
问题描述
我已经阅读了很多关于级联和多对多关联的主题,但是我一直无法找到针对特定问题的答案。
我有UserProfiles和角色之间的多对多关系。当我删除一个UserProfile时,我希望连接表(userprofile2role)中的关联记录可以被数据库删除,所以用一个实际的SQL ON DELETE CASCADE操作。这可能吗?无论我尝试什么,Hibernate总是创建UserProfile表而不指定ON DELETE行为。
UserProfile映射:
@Entity
public class UserProfile {
private Long id;
私人设置<角色>角色;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public final Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
//注意:CascadeType.ALL不适用于多对多关系
@ManyToMany(fetch = FetchType.EAGER)
public Set< ;作用> getRoles(){
返回角色;
}
public void setRoles(Set< Role> roles){
this.roles = roles;
$ b 角色映射:
@Entity
public class Role {
private Long id;
私人设定< UserProfile> userProfiles = new HashSet< UserProfile>();
@Id
@GeneratedValue
public final Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
// CascadeType.REMOVE不会在SQL中创建ON CASCADE DELETE?
@ManyToMany(mappedBy =roles,cascade = CascadeType.REMOVE)
public Set< UserProfile> getUserProfiles(){
返回userProfiles;
}
public void setUserProfiles(Set< UserProfile> userProfiles){
this.userProfiles = userProfiles;
$ b $ p
$ b $不幸的是,不包含ON CASCADE DELETE部分。我尝试在UserProfile中的角色集合和角色中的userprofiles集合(此处显示)上设置CascadeType.REMOVE行为,但无济于事。我们非常欢迎您的建议: - )
CREATE TABLE`px_userprofile2role`(
`userprofile_id` BIGINT(20)NOT NULL,
`role_id` BIGINT(20)NOT NULL,
PRIMARY KEY(`userprofile_id`,`role_id`),
键`FK1C82E84191F65C2B`(`userprofile_id`),
KEY`FK1C82E8416203D3C9`(`role_id`),
约束`FK1C82E8416203D3C9`外键(`role_id`)参考`px_role`(`id`),
约束`FK1C82E84191F65C2B`外键(`userprofile_id`)参考`px_userprofile`(`id`)
)中ENGINE = INNODB默认字符集= LATIN1
解决方案不支持在JPA中为DDL生成 ON DELETE CASCDADE
。级联REMOVE操作的概念不是DDL级别构造。级联是关于以实体为目标的相关实体的级联生命周期操作。它们与数据库中的级联几乎没有任何关系。在JPA 2.0规范中,解释如下:
如果X是一个新的实体,它将被remove操作忽略。但是,如果从X到这些其他实体的
关系用
cascade = REMOVE或cascade = ALL注释元素值进行注释,则
remove操作将级联到由X引用的实体。 / p>
如果X是一个托管实体,则删除操作会导致其被删除
。如果从X到这些其他实体的关系注释为
cascade = REMOVE或cascade = ALL注释元素值,则移除操作将级联到由X引用的实体
。
另外,REMOVE不应该用于@ManyToMany(来自JPA 2.0规范):
关系建模注释约束了
cascade = REMOVE规范的使用。 cascade = REMOVE规范应该仅适用于指定为OneToOne或
OneToMany的关联。将cascade = REMOVE应用于其他
关联的应用程序不可移植。
生成 ON DELETE CASCDADE
来DDL,存在供应商扩展 @ OnDelete 在休眠:
@OnDelete(动作= OnDeleteAction.CASCADE)
I have read a lot of topics regarding cascading and many-to-many associations, but I haven't been able to find an answer to my particular question.
I have a many-to-many relationship between UserProfiles and Roles. When I remove a UserProfile I want the associated records in the join table (userprofile2role) to be removed by the database, so with an actual SQL 'ON DELETE CASCADE' action. Is this possible? Whatever I try, Hibernate always creates the UserProfile table without specifying ON DELETE behaviour.
UserProfile mapping:
@Entity
public class UserProfile {
private Long id;
private Set<Role> roles;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public final Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
// Note: CascadeType.ALL doesn't work for many-to-many relationships
@ManyToMany (fetch = FetchType.EAGER)
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
Role mapping:
@Entity
public class Role {
private Long id;
private Set<UserProfile> userProfiles = new HashSet<UserProfile>();
@Id
@GeneratedValue
public final Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
// CascadeType.REMOVE doesn't create ON CASCADE DELETE in SQL?
@ManyToMany(mappedBy = "roles", cascade = CascadeType.REMOVE)
public Set<UserProfile> getUserProfiles() {
return userProfiles;
}
public void setUserProfiles(Set<UserProfile> userProfiles) {
this.userProfiles = userProfiles;
}
}
The SQL for the join table resulting from these mappings doesn't contain an ON CASCADE DELETE part unfortunately. I tried setting the CascadeType.REMOVE behaviour on both the roles collection in UserProfile and on the userprofiles collection in Role (shown here), but to no avail. Your suggestions are most welcome :-)
CREATE TABLE `px_userprofile2role` (
`userprofile_id` BIGINT(20) NOT NULL,
`role_id` BIGINT(20) NOT NULL,
PRIMARY KEY (`userprofile_id`,`role_id`),
KEY `FK1C82E84191F65C2B` (`userprofile_id`),
KEY `FK1C82E8416203D3C9` (`role_id`),
CONSTRAINT `FK1C82E8416203D3C9` FOREIGN KEY (`role_id`) REFERENCES `px_role` (`id`),
CONSTRAINT `FK1C82E84191F65C2B` FOREIGN KEY (`userprofile_id`) REFERENCES `px_userprofile` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=latin1
解决方案 There is no support for generating ON DELETE CASCDADE
to DDL in JPA. Concept of cascading REMOVE operation is not DDL level construct. Cascades are about cascading lifecycle operations that targets to entity to the related entities. They have quite much nothing to do with cascades in database. In JPA 2.0 specification this is explained as follows:
If X is a new entity, it is ignored by the remove operation. However,
the remove operation is cascaded to entities referenced by X, if the
relationship from X to these other entities is annotated with the
cascade=REMOVE or cascade=ALL annotation element value.
If X is a managed entity, the remove operation causes it to become
removed. The remove operation is cascaded to entities referenced by X,
if the relationships from X to these other entities is annotated with
the cascade=REMOVE or cascade=ALL annotation element value.
Also REMOVE should not be used with @ManyToMany (from JPA 2.0 spec.):
The relationship modeling annotation constrains the use of the
cascade=REMOVE specification. The cascade=REMOVE specification should
only be applied to associations that are specified as OneToOne or
OneToMany. Applications that apply cascade=REMOVE to other
associations are not portable.
What it comes to the generating ON DELETE CASCDADE
to DDL, there is vendor extension @OnDelete in Hibernate:
@OnDelete(action=OnDeleteAction.CASCADE)
这篇关于在JPA2多对多关系上执行CASCADE DELETE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!