【问题标题】:ON CASCADE DELETE on JPA2 many-to-many relationshipJPA2多对多关系上的级联删除
【发布时间】:2013-05-11 22:56:32
【问题描述】:

我已经阅读了很多关于级联和多对多关联的主题,但我无法找到我的特定问题的答案。

我在 UserProfiles 和 Roles 之间有一个多对多的关系。当我删除用户配置文件时,我希望数据库删除连接表 (userprofile2role) 中的关联记录,因此使用实际的 SQL 'ON DELETE CASCADE' 操作。这可能吗?无论我尝试什么,Hibernate 总是在不指定 ON DELETE 行为的情况下创建 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

【问题讨论】:

    标签: hibernate many-to-many jpa-2.0 cascade sql-delete


    【解决方案1】:

    不支持在 JPA 中生成 ON DELETE CASCDADE 到 DDL。级联 REMOVE 操作的概念不是 DDL 级别的构造。级联是将针对实体的生命周期操作级联到相关实体。它们与数据库中的级联几乎没有关系。在 JPA 2.0 规范中解释如下:

    如果 X 是一个新实体,它会被删除操作忽略。然而, 删除操作级联到 X 引用的实体,如果 从 X 到这些其他实体的关系用 cascade=REMOVE 或 cascade=ALL 注释元素值。

    如果 X 是一个托管实体,则删除操作会使其变为 删除。删除操作级联到 X 引用的实体, 如果从 X 到这些其他实体的关系被注释为 cascade=REMOVE 或 cascade=ALL 注释元素值。

    REMOVE 也不应与 @ManyToMany 一起使用(来自 JPA 2.0 规范):

    关系建模注释限制了 级联=删除规范。 cascade=REMOVE 规范应该 仅适用于指定为 OneToOne 或 一对多。将 cascade=REMOVE 应用于其他应用程序的应用程序 关联不可移植。

    关于生成ON DELETE CASCDADE 到 DDL,Hibernate 中有供应商扩展 @OnDelete

    @OnDelete(action=OnDeleteAction.CASCADE)
    

    【讨论】:

    • 我在多对多关系中使用@OnDelete 时出错,但我不想将我的应用程序绑定到Hibernate。我将创建一个不同的解决方案并删除应用程序级别的记录。谢谢你的解释。
    猜你喜欢
    • 2016-04-11
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多