【问题标题】:JPA Many-to-Many relation: delete child entity not possible with active relationJPA多对多关系:使用活动关系无法删除子实体
【发布时间】:2018-05-14 12:11:31
【问题描述】:

在数据库中,我有 UserRole 实体。共享多对多关系,因为Role 实体可以分配给多个User 实体,另一方面User 实体可以分配给多个Role 实体。

我的实体类是这样的

用户实体

@Entity
public class UserEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column(unique = true, nullable = false)
    private String username;
    @ManyToMany
    private Set<RoleEntity> roles;

    ...
}

角色实体

@Entity
public class RoleEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column(unique = true, nullable = false)
    private String name;
    @ManyToMany(mappedBy = "roles")
    private Set<UserEntity> users;

    ...
}

通过这种配置,我可以将实体相互映射。我还可以删除 User 实体。但只要存在关系,我就无法删除Role 实体。

如果我添加 cascade = CascadeType.REMOVERole 会被删除,但 User 当然也会随之删除。

目前实现此功能的唯一方法是在两侧定义@JoinTable。但这似乎更像是一种解决方法。我究竟做错了什么?由于这是一个常规用例,因此必须有解决方案,尽管我还没有找到它......

【问题讨论】:

  • 您是否检查过您的映射在数据库中的外观?如果我没记错的话,如果你不添加@JoinTable,那么数据库中实际发生的是两个连接表,它们由 hibernate 以某种方式管理。这可能会给您带来一些问题。
  • 我不知道这两个表。 JPA 规范确实声明应该只有一个表:JavaPersistence

标签: java hibernate jpa


【解决方案1】:

您需要连接表,这不是一种解决方法。请记住,您正在将您的面向对象模型映射到关系模型。在关系模型中表达多对多关系的唯一方法是定义@JoinTable。

更新:在答案中添加评论
您应该只在一个实体中定义@JoinTable,例如RolesEntity 中的UserEntitymappedBy="roles" 继承了@JoinColumn@JoinTable 名称的定义。

然后你需要定义你想要在关系的两边执行的级联操作。

RoleEntity

@ManyToMany(mappedBy = "roles")
private Set<UserEntity> users;

UserEntity

@ManyToMany
@JoinTable(...)
private Set<RoleEntity> roles;

【讨论】:

  • 我不喜欢这种方法的是,我会有双重定义。我刚刚看到的另一件事是@PreRemove 标签。我向Role 实体添加了一个PreRemove 方法,在该实体中我从它的所有User 中删除了该角色,它也可以工作。 @JoinTable 的好处是,它看起来更流畅,而且我没有任何双重定义。
  • 双重定义是什么意思? mappedBy 旨在继承其他实体中的关系定义。
  • 对不起,我的错。我们目前有一个@JoinTable 的自定义命名,当然需要在双方声明。
  • 为什么?您应该只在一个实体中定义@JoinTable,例如RolesEntity 中的UserEntitymappedBy="roles" 继承了@JoinColumn 和@JoinTable 名称的定义。
  • 等等,当我尝试删除与 User 有关系的 Role 时,我再次遇到约束异常
猜你喜欢
  • 2013-04-25
  • 2021-08-08
  • 1970-01-01
  • 2021-05-25
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
相关资源
最近更新 更多