java - JPA 未获取数据引发 stackoverflow 错误
问题描述
我有一个非常大的 json 来存储,我将它分成以下五个实体并尝试使用 spring-data-jpa 存储到 h2 数据库,插入到数据库中工作正常,但是在获取具有主键 ID 的对象时,我是得到stackoverflow错误,因为存在循环依赖。
有人可以帮我找出问题所在。
顶级
@Entity
@Table(name = "a")
@Data
public class A{
@Id
@Column(name = "a_id")
private String id;
@Column
private String name;
@Column
private String name2;
@Column
private String name3;
@Column
private String name4;
@Column
private String name5;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "a",fetch =
FetchType.EAGER)
@JsonManagedReference
private List<B> b;
}
二等舱
@Entity
@Table(name = "b")
@Data
public class B{
@Id
@Column(name = "bname")
private String bname;
@Column
private String bVersion;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "b")
@JsonManagedReference
private List<C> cs;
@ManyToOne
@JoinColumn(name = "a_id")
@JsonBackReference
private A a;
}
三等舱
@Entity
@Data
public class C{
@Id
@Column(name = "cname")
private String cName;
@Column
private String cVersion;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "c")
@JsonManagedReference
private List<D> ds;
@ManyToOne
@JoinColumn(name = "bname")
@JsonBackReference
private B b;
}
四等
@Entity
@Data
public class D{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="d_id")
private long id;
@Column
private String dName;
@Column
private String dName2;
@ElementCollection
@Column
private List<String> dNames;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "d")
@JsonManagedReference
private List<E> e;
@ManyToOne
@JoinColumn(name = "cname")
@JsonBackReference
private C c;
}
Fifth class
@Entity
@Data
public class E{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "e_id")
private long id;
@Column
private String ename;
@Column
private String eName2;
@ManyToOne
@JoinColumn(name = "e_id")
@JsonBackReference
private E e;
}
解决方案
我也遇到了同样的问题,花了一整天的时间。最后,我发现它的问题toString
在于 Lombok 使用@Data
注解生成的方法。
解决方案:
覆盖、toString
方法和编写您自己的实现。如果您不想使用,请toString
使用@Getter
and@Setter
而不是@Data
.
为什么
注意:这发生在双向关系中。可以说我有两个实体并且具有双向关系。
@data
Entity1{
@oneToMany
public List<Entity2> entity2s;
//Added by lombok while using @Data
@Generated
public String toString() {
return "entity2s=" + this.getEntity2s() + ")";
}
}
@data
Entity2{
@ManytoOne
public Entity1 entity1;
//Added by lombok while using @Data
@Generated
public String toString() {
return "entity1=" + this.getEntity1() + ")";
}
}
toString()
在上面的示例中,Entity1 调用Entity2 和toString()
Entity2 调用Entity1的 toString()(由 JPA 调用)toString()
。这就是循环引用的构建方式。
注:方法同理hashCode
。
这是一些参考链接,
https://github.com/rzwitserloot/lombok/issues/1007
https://interviewbubble.com/stackoverflow-tostring-method-when-using-lombok/
推荐阅读
- r - 使用 R 可视化多元线性回归
- python - 有没有办法用 Airflow 对 Dag 中的 BigQueryOperators 进行参数化?
- python - 将图像转换为 MNIST 格式
- javascript - p-dialog 既不是应有的样式,也不是出现/消失
- tomcat - Tomcat 10.x 在 javax.servlet 上抛出 java.lang.NoClassDefFoundError。*
- pandas - Jupyter 笔记本,ImportError:无法导入所需的依赖项:
- javascript - 我对异步函数的布尔返回有疑问
- django - 过滤与我在一个查询中提供的实例 ID 具有相同字段的实例?
- sql - 在 SQL 中转置列和行的快速和最佳方法?
- python - 从未定义的文件python获取文件扩展名