I work with JPA, Hibernate, Spring boot
I have a jpa issue : when I save an entity that own a ManyToMany association with CascadeType.MERGE property, the child entity is created while it already exist in the database table
I have the following entity
@Entity
@Table(name = "ENTITY")
@NoArgsConstructor
@AllArgsConstructor
public class EntityList implements Serializable {
........................
........................
@ManyToMany(cascade=CascadeType.MERGE)
@JoinTable( name = "entity_delegate",
joinColumns = @JoinColumn(name = "entity_id"),
inverseJoinColumns = @JoinColumn(name = "utilisateur_id") )
private List<Utilisateur> delegates = new ArrayList<>();
.......................
.......................
}
The Utilisateur Entity is the following
@Entity
@Table(name = "UTILISATEUR")
@NoArgsConstructor
@AllArgsConstructor
public class Utilisateur implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull
private Integer id;
private String firstname;
private String lastname;
private String accountAD;
private String fonction;
.....................
.....................
}
In the database the following Utilisateur already exists in the database
id firstname lastname accountad fonction
44 "StaffAccess02" "FINS" "StaffAccess02" null
When I apply the following code
EntityList entity = entityListList.get(0);
List<Utilisateur> delegates = new ArrayList<>();
delegates.add(new Utilisateur("StaffAccess02", "FINS", "StaffAccess02", null));
entity.setDelegates(delegates);
entity = entityListRepository.save(entity);
a second row with the same column value is created :
id firstname lastname accountad fonction
51 "StaffAccess02" "FINS" "StaffAccess02" null
How to prevent this ?
CodePudding user response:
Though CascadeType.MERGE is used, the id column of the child entity is autogenerated id.
List<Utilisateur> delegates = new ArrayList<>();
delegates.add(new Utilisateur("StaffAccess02", "FINS", "StaffAccess02", null));
entity.setDelegates(delegates);
This code creates a new record by adding anew sequence number in the id column each time it is being saved.
Solution 1: Remove @GeneratedValue and mention the id value in the constructor
new Utilisateur(44,"StaffAccess02", "FINS", "StaffAccess02", null)
Solution 2: get the arraylist from db and then modify the child entity before saving
Utilisateur u=UtilisateurRepository.getById(44);
//modify u object here
List<Utilisateur> delegates = new ArrayList<>();
delegates.add(u);
entity.setDelegates(delegates);