首页 > 解决方案 > session#refresh 不使用@ManyToOne 和复合键刷新根实体

问题描述

我有以下实体和映射:

@Entity
public class Father {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @OneToMany(mappedBy = "father", cascade = CascadeType.ALL)
    private Set<Child> childs = new HashSet<>();

    // getters and setters

}

@Entity
@IdClass(Child.ChildPk.class)
public class Child {

    @Id
    @JoinColumn(name = "father_id")
    @ManyToOne(optional = false)
    private Father father;

    @Id
    @Column(name = "name")
    private String name;

    public Child() {

    }

    // getters and setters

    static class ChildPk implements Serializable {

        private Father father;
        private String name;

        // getters and setters
        // equals and hashcode on both father and name
    }
}

如您所见,我的Child类在其所有成员上都有一个复合键,包括其@OneToMany指向Father.

我遇到的问题如下:当我尝试刷新一个Father实体(session.refresh(father))时,它没有正确刷新:子被重新加载,并且子里面的父亲也是,但不是根父亲。

我试图在简化的上下文中重现(使用 H2 和 JPA 的简单 Spring Boot 项目,现在由于实体加载的无限循环而出现 StackOverflow 错误)。

我的映射有问题吗?

这是重现错误的 github 项目:https ://github.com/bpagnier/test-jpa

谢谢 !:)

标签: javahibernatejpa

解决方案


有人帮我找到了解决方案:通过删除 OneToMany 的 Cascade 配置来改变REFRESH它的工作原理!

前 :

@OneToMany(mappedBy = "father", cascade = CascadeType.ALL)

后 :

@OneToMany(mappedBy = "father", cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})


推荐阅读