Search code examples
javapostgresqljpaspring-data-jpamany-to-many

Remove the first entity and its relationship without removing the second entity - Spring Data JPA


I have two entities, one of UserEntity and the other RoleEntity, the user can have multiple roles and the role can be used by multiple users, my entities look like:

@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;
}

Generally roles are fixed they don't change a lot. Now I have a service:

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

My requirement is to remove only the user and not the roles related with this user, which mean remove the user and the relation ship. When I call the previews method I got.

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".

Is there any trick to solve this please?


Solution

  • I solved my issue like this, I'm not sure if this is a best approach to solve this:

    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!");
        }
    }