我已经阅读了许多有关级联和多对多关联的主题,但是我无法找到我的特定问题的答案。
我在UserProfiles和Roles之间有多对多关系。当我删除UserProfile时,我希望数据库删除联接表(userprofile2role)中的关联记录,因此要使用实际的SQL’ON DELETE CASCADE’操作。这可能吗?无论我尝试什么,Hibernate总是在不指定ON DELETE行为的情况下创建UserProfile表。
UserProfile映射:
@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; } }
角色映射:
@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; } }
不幸的是,这些映射生成的联接表的SQL不包含ON CASCADE DELETE部分。我尝试在UserProfile中的角色集合和Role中的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`), 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
不支持ON DELETE CASCDADE在JPA中生成DDL。级联的REMOVE操作的概念不是DDL级别的构造。级联是关于级联的生命周期操作,该操作针对的是实体到相关实体。它们与数据库中的级联无关。在JPA 2.0规范中,解释如下:
ON DELETE CASCDADE
如果X是新实体,则remove操作将忽略它。但是,如果从X到这些其他实体的关系用cascade = REMOVE或cascade = ALL标注元素值标注,则移除操作将层叠到X引用的实体。 如果X是一个受管实体,则删除操作会使它被删除。如果从X到这些其他实体的关系使用层叠= REMOVE或层叠= ALL标注元素值标注,则remove操作将层叠到X引用的实体。
如果X是新实体,则remove操作将忽略它。但是,如果从X到这些其他实体的关系用cascade = REMOVE或cascade = ALL标注元素值标注,则移除操作将层叠到X引用的实体。
如果X是一个受管实体,则删除操作会使它被删除。如果从X到这些其他实体的关系使用层叠= REMOVE或层叠= ALL标注元素值标注,则remove操作将层叠到X引用的实体。
此外,REMOVE不应与@ManyToMany一起使用(来自JPA 2.0规范):
关系建模注释限制了cascade = REMOVE规范的使用。级联=删除规范仅应应用于指定为OneToOne或OneToMany的关联。将Cascade = REMOVE应用于其他关联的应用程序不可移植。
生成ON DELETE CASCDADEDDL 涉及到什么,Hibernate中有供应商扩展@OnDelete:
@OnDelete(action=OnDeleteAction.CASCADE)