JPA2中的多对多关系中的ON CASCADE DELETE

6
我读了许多关于级联和多对多关联的主题,但我还没有找到我的问题的答案。
我有一个用户配置文件(UserProfiles)和角色(Roles)之间的多对多关系。当我删除一个用户配置文件时,我希望数据库删除join表(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中的roles集合和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
1个回答

10
在JPA中,没有支持生成ON DELETE CASCDADE到DDL的功能。级联删除操作的概念不是DDL级别的结构。级联是关于对目标实体和相关实体进行级联生命周期操作。它们与数据库中的级联几乎没有任何关系。在JPA 2.0规范中,解释如下:
如果X是一个新实体,则删除操作会忽略它。但是,如果从X到其他实体的关系使用cascade=REMOVE或cascade=ALL注释元素值进行了注释,则删除操作会级联到这些其他实体。
如果X是托管实体,则删除操作导致其被删除。如果从X到这些其他实体的关系使用cascade=REMOVE或cascade=ALL注释元素值进行了注释,则删除操作会级联到这些其他实体。
此外,不应将REMOVE与@ManyToMany一起使用(来自JPA 2.0规范):
关系建模注释限制了cascade=REMOVE规范的使用。cascade=REMOVE规范只应用于指定为OneToOne或OneToMany的关联。将cascade=REMOVE应用于其他关联的应用程序不可移植。
当涉及到在DDL中生成ON DELETE CASCDADE时,Hibernate中有供应商扩展@OnDelete
@OnDelete(action=OnDeleteAction.CASCADE)

2
我在使用@OnDelete时遇到了错误,但是无论如何我都不想将我的应用程序与Hibernate绑定。我会创建一个不同的解决方案,并在应用程序级别上删除记录。感谢您的解释。 - Julius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接