Home > Software design >  duplicate row in database created with ManyToMany association and cascadeType. MERGE
duplicate row in database created with ManyToMany association and cascadeType. MERGE

Time:12-28

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);
  • Related