在JPA2多对多关系上执行CASCADE DELETE [英] ON CASCADE DELETE on JPA2 many-to-many relationship

查看:177
本文介绍了在JPA2多对多关系上执行CASCADE DELETE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆