I have a system where I have users and each one can have several roles.
@Entity
@Table(
uniqueConstraints=
@UniqueConstraint(columnNames={"username"})
)
public class CustomUser implements UserDetails {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String email;
private String firstName;
private String lastName;
/* Spring Security related fields*/
@OneToMany(fetch = FetchType.EAGER)
private List<Role> authorities;
[...]
}
I receive a user to add along with their roles, which, to avoid having to repeatedly save the same role in the database, what I do is obtain it from the database, if it does not exist, I add it, and if there is, assign it to my user.
private List<Role> getRoles(List<Role> userAuthorities) {
List<Role> newRoles = new ArrayList<Role>(); // Lista con los nombres de los roles
// Busco si existe, y si no existen los agrego
for (Role role : userAuthorities) {
Role existingRole = this.getRoleRepository().findOneByName(role.getName()).orElse(null);
// Si no existe lo agrego
if (existingRole == null) {
this.getRoleRepository().save(role);
newRoles.add(role);
} else {
newRoles.add(existingRole);
}
}
return newRoles;
}
@Override
public CustomUserDTO create(CustomUserDTO userDto) {
List<Role> roles = this.getRoles(userDto.getAuthorities());
CustomUser user = this.getTransformer().toEntity(userDto);
user.setAuthorities(roles); // Asigno los roles
this.getUserRepository().save(user);
return this.getTransformer().toDTO(user); // Devuelvo a DTO el usuario recien creado
}
When I raise a user whose role is not yet in the DB there is no problem. But when it exists in the DB, I assign it to my user and I save it to the latter. I get the following error:
"could not execute statement; SQL [n / a]; constraint ["UK_735R7F0TONHSBGBPXMMRRC0MS_INDEX_8 ON PUBLIC.CUSTOM_USER_AUTHORITIES (AUTHORITIES_ID) VALUES (3, 3) "; SQL statement: insert into custom_user_authorities (custom_user_id, authorities_id) values (?,?) [23505-197]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement "
That is, you are trying to insert the role with the same ID again and there it breaks.
How can I get the existing role to reuse it, assign it to my user, save that user without exploiting it?
Thank you very much