Tengo el siguiente código:
groupModel.getUserFormGroups().clear(); for(MemberDTO member : group.getMembers()){ User u = userRepository.findByEmail(member.getEmail()); System.out.println(member.getEmail() + " " + groupModel.getName() + " " + member.getRole()); if(u == null){ return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } groupModel.getUserFormGroups().add(new UserFormGroup(u, groupModel, UserFormGroupRole.ADMIN)); } try{ groupRepository.save(groupModel); return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); } catch (DataIntegrityViolationException e){ System.out.println(e.getMessage()); System.out.println(e.getClass()); return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).build(); } Cuando ejecuto esto, los nuevos UserFormGroups tienen una identificación y todos los demás campos son nulos. ¿Hay algún problema con la actualización completa de una relación ManyToOne?
En la entidad del grupo tengo la siguiente relación OneToMany:
@OneToMany(targetEntity=UserFormGroup.class, cascade = { CascadeType.PERSIST, CascadeType.REMOVE }, fetch = FetchType.EAGER, mappedBy = "formGroup", orphanRemoval=true) private Set<UserFormGroup> userFormGroups = new HashSet<>();Y la relación UserFormGroup se ve así:
@Entity @Table(uniqueConstraints={ @UniqueConstraint(columnNames = {"user", "form_group"}) }) public class UserFormGroup implements Serializable{ @Id @GeneratedValue(strategy= GenerationType.AUTO) private long id; @ManyToOne @JoinColumn(name = "user",referencedColumnName = "id") private User user; @ManyToOne @JoinColumn(name = "form_group", referencedColumnName = "id") private FormGroup formGroup; @Column(name = "role") private UserFormGroupRole role; public UserFormGroup() { } public UserFormGroup(User user, FormGroup group, UserFormGroupRole role) { this.user = user; this.formGroup = group; this.role = role; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public FormGroup getFormGroup() { return formGroup; } public void setFormGroup(FormGroup formGroup) { this.formGroup = formGroup; } public UserFormGroupRole getRole() { return role; } public void setRole(UserFormGroupRole role) { this.role = role; } }No al 100%, pero en mi opinión, el problema podría ser el siguiente:
La implementación de CrudRepository del método save verifica si el objeto que está guardando es una entidad nueva o existente. Si ya es una entidad existente, realiza una operación de merge . Este sería el escenario que está sucediendo en su caso, ya que groupModel es una entidad existente.
Ahora, en la dependencia @OneToMany , solo tiene estas opciones en cascada:
cascade = { CascadeType.PERSIST, CascadeType.REMOVE }
Si agrega CascadeType.MERGE , la operación debe propagarse a las entidades UserFromGroup y conservarlas (el comportamiento predeterminado de fusión cuando las entidades son nuevas).