删除第一个实体及其关系而不删除第二个实体 - Spring Data JPA
Remove the first entity and its relationship without removing the second entity - 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
的所有引用设为空。
所以基本上是什么问题?虽然 RolesEntity
引用了 UsersEntity
class,但您不能删除它。最简单的事情是为 UsersEntity
class 中的每个 RolesEntity
创建一个循环并从中删除所有内容。
然后您就可以从您的数据库中成功删除该用户了。
查看此以获取更多信息:How to remove entity with ManyToMany relationship in JPA (and corresponding join table rows)?
我这样解决了我的问题,我不确定这是否是解决此问题的最佳方法:
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;
我有两个实体,一个是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
的所有引用设为空。
所以基本上是什么问题?虽然 RolesEntity
引用了 UsersEntity
class,但您不能删除它。最简单的事情是为 UsersEntity
class 中的每个 RolesEntity
创建一个循环并从中删除所有内容。
然后您就可以从您的数据库中成功删除该用户了。
查看此以获取更多信息:How to remove entity with ManyToMany relationship in JPA (and corresponding join table rows)?
我这样解决了我的问题,我不确定这是否是解决此问题的最佳方法:
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;