【问题标题】:duplicate row in database created with ManyToMany association and cascadeType. MERGE使用 ManyToMany 关联和 cascadeType 创建的数据库中的重复行。合并
【发布时间】:2021-12-27 15:30:53
【问题描述】:

我使用 JPA、Hibernate、Spring boot

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

我有以下实体

@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

如何预防?

【问题讨论】:

    标签: spring-boot hibernate jpa


    【解决方案1】:

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

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

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

    方案一:去掉@GeneratedValue,在构造函数中提及id值

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

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

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

    【讨论】:

      猜你喜欢
      • 2016-11-03
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      相关资源
      最近更新 更多