I'm trying to update my entity many to many by this json: as you can see i have this relation: Utente-Ruoli, Ruoli-Privileggi
this is the method in my Utente JPA:
@Modifying(flushAutomatically = true, clearAutomatically = true)
@Transactional
@Query("UPDATE Utente u SET u.roles = :roles WHERE u.id = :userId")
int saveUserRoles(@Param("userId") Integer userId, @Param("roles") Set<Ruoli> roles);
and this is where i perfom the service:
public Utente addRolesToUser(RuoliDTO ruoliDTO) {
log.info("{}.addRolesToUser adding user: {} to list roles: {}", this.getClass().getName(), ruoliDTO.getUser().getUsername(), ruoliDTO.getRoles().size());
Utente utente = ruoliDTO.getUser();
Set<Ruoli> rolesToAdd = ruoliDTO.getRoles();
utente.setRoles(ruoliDTO.getRoles());
userRepository.saveUserRoles(utente.getId(), rolesToAdd);
return utente;
}
And i get always this error:
Parameter value [Ruoli{id=2, roleName='ADMIN', description='admin', privileggi=[Privileggi{id=1, privName='UNICACON_MDJS_USER', description='basic user', active=false}, Privileggi{id=3, privName='UNICACON_MDJS_ADMIN', description='admin role', active=true}, Privileggi{id=4, privName='ARCHICON_MDJS_USER', description='archicon role', active=true}]}] did not match expected type [java.util.Set (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [Ruoli{id=2, roleName='ADMIN', description='admin', privileggi=[Privileggi{id=1, privName='UNICACON_MDJS_USER', description='basic user', active=false}, Privileggi{id=3, privName='UNICACON_MDJS_ADMIN', description='admin role', active=true}, Privileggi{id=4, privName='ARCHICON_MDJS_USER', description='archicon role', active=true}]}] did not match expected type [java.util.Set (n/a)]
These are my entities:
@Entity
@Table(name = "utente")
@Data
public class Utente implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@JsonIgnoreProperties("utenti")
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST})
@JoinTable(
name = "utente_ruolo",
joinColumns = @JoinColumn(name = "utente_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
)
private List<Ruoli> roles;
}
@Data
@Entity
@Table(name = "ruoli")
public class Ruoli implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@JsonIgnore
@ManyToMany(cascade ={ CascadeType.MERGE, CascadeType.PERSIST})
@JoinTable(
name = "utente_ruolo",
joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "utente_id", referencedColumnName = "id")
)
private List<Utente> utenti;
}
@Entity
@Data
@Table(name = "privileggi")
public class Privileggi implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "priv_name")
private String privName;
@Column(name = "description")
private String description;
@Column(name = "active")
private Boolean active;
@JsonIgnore
@ManyToMany( cascade ={ CascadeType.MERGE, CascadeType.PERSIST})
@JoinTable(
name = "ruolo_privileggi",
joinColumns = @JoinColumn(name = "priv_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
)
private List<Ruoli> ruoli;
}
What Am I doing wrong?
Here is the answer shown below
First, you need to fetch the Utente entity from the database.
Then, you can update the Utente entity's roles with the roles from the RuoliDTO.
Finally, you can save the updated Utente entity back to the database.
public Utente addRolesToUser(RuoliDTO ruoliDTO) {
log.info("{}.addRolesToUser adding user: {} to list roles: {}", this.getClass().getName(), ruoliDTO.getUser().getUsername(), ruoliDTO.getRoles().size());
// 1. Fetch the Utente entity from the database.
Utente utente = userRepository.findById(ruoliDTO.getUser().getId()).orElse(null);
if (utente != null) {
// 2. Update the Utente entity's roles with the roles from RuoliDTO.
utente.setRoles(ruoliDTO.getRoles());
// 3. Save the updated Utente entity back to the database.
utente = userRepository.save(utente);
}
return utente;
}