删除第一个实体及其关系而不删除第二个实体 - Spring Data JPA



我有两个实体,一个是UserEntity,另一个是RoleEntity,用户可以有多个角色,角色可以由多个用户使用,我的实体看起来像:

@Entity
public class UsersEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
private Long id;
//...
@ManyToMany(mappedBy = "users")
private Set<RolesEntity> roles;
//...
// Getters and setters
}
<小时 />
@Entity
public class RolesEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
private Integer id;
@NotNull
@Enumerated(EnumType.STRING)
@Column(length = 20)
private RoleEnum name;
@JoinTable(name = "user_roles", joinColumns = {
@JoinColumn(name = "role_id", referencedColumnName = "id", nullable = false)}, inverseJoinColumns = {
@JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)})
@ManyToMany
private List<UsersEntity> users;
}

一般来说,角色是固定的,它们不会改变太多。现在我有一项服务:

public void removeUser(Long id) {
if (userRepository.findById(id).isPresent()) {
userRepository.deleteById(id);
} else {
throw new IllegalArgumentException("User not found!");
}
}

我的要求是仅删除用户,而不删除与此用户相关的角色,这意味着删除用户和关系船。当我调用预览方法时,我得到了。

org.postgresql.util.PSQLException: ERROR: update or delete on table "users" violates foreign key constraint "constraint_user_id" on table "user_roles"
Detail: Key (id)=(4) is still referenced from table "user_roles".

有什么技巧可以解决这个问题吗?

您需要对该UsersEntity的任何引用都为 null。

那么基本上问题出在哪里?虽然RolesEntity具有对该UsersEntity类的引用,但您无法删除该类。要做的最简单的事情是为UsersEntity类中的每个RolesEntity创建一个循环,并从中删除所有内容。

然后,您可以从数据库中成功删除该用户。

查看此内容以获取更多信息: 如何在 JPA 中删除具有多对多关系的实体(以及相应的连接表行(?

我这样解决了我的问题,我不确定这是否是解决此问题的最佳方法:

public void removeUser(Long id) {
Optional<UsersEntity> userById = usersRepository.findById(id);
if (userById.isPresent()) {
UsersEntity user = userById.get();
for (RolesEntity role : user.getRoles()) {
role.setUsers(null);
rolesRepository.save(role);
}
usersRepository.delete(user);
} else {
throw new IllegalArgumentException("User not found!");
}
}

我认为你可以通过使用CascadeType.REMOVE

@ManyToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER)
@JoinTable(
name = "users_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private List<Role> roles;

最新更新