使用 ManyToMany 关联和 cascadeType 创建的数据库中的重复行。合并

duplicate row in database created with ManyToMany association and cascadeType. MERGE

我使用 JPA、Hibernate、Spring boot

我有一个 jpa 问题:当我保存一个拥有与 CascadeType.MERGE 的 ManyToMany 关联的实体时 属性,子实体在数据库中已存在时创建 table

我有以下实体

@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<>();
    
.......................
.......................
}

Utilisateur 实体如下

@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;
    .....................
    .....................
}

在数据库中,数据库中已存在以下 Utilisateur

id   firstname      lastname   accountad       fonction
44  "StaffAccess02" "FINS"  "StaffAccess02"      null

当我应用以下代码时

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

已创建具有相同列值的第二行:

id   firstname      lastname   accountad       fonction
51  "StaffAccess02" "FINS"  "StaffAccess02"      null

如何防止这种情况?

虽然使用了CascadeType.MERGE,但是子实体的id列是自动生成的id。

List<Utilisateur> delegates = new ArrayList<>();
delegates.add(new Utilisateur("StaffAccess02", "FINS", "StaffAccess02", null));
entity.setDelegates(delegates);

此代码通过在每次保存时在 id 列中添加新序列号来创建新记录。

解决方案 1:删除 @GeneratedValue 并在构造函数中提及 id 值

new Utilisateur(44,"StaffAccess02", "FINS", "StaffAccess02", null)

方案二:从db中获取arraylist,然后在保存前修改子实体

Utilisateur u=UtilisateurRepository.getById(44);
//modify u object here
List<Utilisateur> delegates = new ArrayList<>();
delegates.add(u);
entity.setDelegates(delegates);