【问题标题】:Hibernate - In a one-to-many relationship, a child loses references to the parent when updatingHibernate - 在一对多关系中,孩子在更新时会丢失对父母的引用
【发布时间】:2021-06-25 09:56:44
【问题描述】:

如题,在执行更新操作时,前一个子级丢失了对父级的引用。

父方

@OneToMany(cascade =CascadeType.ALL)
@JoinColumn(name = "individual_id")
private List<ContactMedium> contactMedium;

儿童方面

@Entity
@Table(name = "contactMedium")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ContactMedium 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id ;

    @ManyToOne
    private Individual individual;

补丁操作

 public Individual patch(Individual individual, Long id) {
        Individual objectToSave = individual;
        objectToSave.setId(id);
        return individualRepository.save(objectToSave);
    }

更新时,先前的属性会丢失对子项的引用。我怎样才能防止这种情况发生?

【问题讨论】:

  • 可能是 fetch = FetchType.LAZY 的问题?
  • 为什么在更新parent时需要更新id?
  • 我不想更新 id,我只需要两个对我个人 id 的引用
  • “前一个孩子”是什么意思?进行更新时,列表中是否缺少“上一个孩子”?

标签: java hibernate spring-data-jpa hibernate-mapping cascade


【解决方案1】:

您应该首先使用 ID 从数据库中检索实体,然后更新特定字段并将更新后的实体保留回来。

【讨论】:

    【解决方案2】:

    我认为您必须在@ManyToOne 中添加@OneToMany(mappedBy="individual" , cascade =CascadeType.PERSIST)@JoinColumn,如下所示:

    @OneToMany(mappedBy = "individual", cascade =CascadeType.PERSIST)
    private List<ContactMedium> contactMedium;
    
    @ManyToOne
    @JoinColumn(name = "individual_id")
    private Individual individual;
    

    【讨论】:

    • 没用,我的写反了但是没有错
    • 能否在更新前尝试获取列表 getcontactMedium 并将其重新分配给 objectTosave,例如:'objectToSave.setContactMedium(individual.getContactMedium());'
    • 好的,我建议改用 CascadeType.PERSIST 或 CascadeType.ALL
    【解决方案3】:

    您的映射似乎有误。理想情况下,它们应该如下所示:

    @Entity
    @Table(name = "contactMedium")
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class ContactMedium 
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id ;
    
        @ManyToOne 
        @JoinColumn
        private Individual individual;
    

    @OneToMany(mappedBy = "individual", cascade = CascadeType.ALL)
    private List<ContactMedium> contactMedium;
    

    你需要保存ContactMediumIndividual会自动保存。这里ContactMedium 具有对Individual 的外键引用(这就是您的数据库表屏幕截图中描述的内容)。

    【讨论】:

    • 没用,我的写反了但没错
    • 您在contact_medium 表中有individual_id 对吗?而individual 表没有contact_medium_id
    【解决方案4】:

    通常使用mappedBy 作为@OneToMany 的参数而不是@JoinColumn 来建立双向关系。

    你能不能试着改变一下

    @OneToMany(cascade =CascadeType.ALL)
    @JoinColumn(name = "individual_id")
    private List<ContactMedium> contactMedium;
    

    @OneToMany(mappedBy = "individual", cascade =CascadeType.ALL)
    private List<ContactMedium> contactMedium;
    

    看看效果好不好?

    【讨论】:

    • 不幸的是,它没有改变
    • OK... 您可能想要打开生成的 sql 的日志记录,看看何时与预期的 sql 不同。
    猜你喜欢
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2020-06-21
    • 2015-04-18
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多