ON CASCADE DELETE在JPA 2中的多对多关系

时间:2013-05-11 22:56:33

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

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

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

1 个答案:

答案 0 :(得分:8)

在JPA中不支持为DDL生成ON DELETE CASCDADE。级联REMOVE操作的概念不是DDL级别构造。级联是关于级联生命周期操作,其目标是实体到相关实体。它们与数据库中的级联无关。在JPA 2.0规范中,这解释如下:

  

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

     

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

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

  

关系建模注释约束了使用   cascade = REMOVE规范。级联= REMOVE规范应该   仅适用于指定为OneToOne或的协会   一对多。将cascade = REMOVE应用于其他应用程序的应用程序   协会不可携带。

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

@OnDelete(action=OnDeleteAction.CASCADE)