-1

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?

Doesn't Matter
  • 1,061
  • 3
  • 11
  • 29

3 Answers3

1

You need to make any references to that UsersEntity to be null.

So basically what is the problem? While RolesEntity has a reference to that UsersEntity class you cannot delete that. The most trivial thing to do is to make a loop for each RolesEntity in your UsersEntity class and remove everything from it.

Then you can successfully delete that user from your db.

Check this out to get more info: How to remove entity with ManyToMany relationship in JPA (and corresponding join table rows)?

Antaaaa
  • 233
  • 3
  • 14
0

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!");
    }
}
Doesn't Matter
  • 1,061
  • 3
  • 11
  • 29
0

I think you can do this by using 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;
dassoop
  • 11
  • 2