我有 2 个域类,PO 类和产品类,PO 类中有一个列表。所以Product对PO是ManyToOne,PO对Product是OneToMany。
public class PO {
....
@OneToMany(mappedBy = "po", cascade= CascadeType.ALL, orphanRemoval=true)
private List<Product> products = new ArrayList<>();
.....
}
public class Product {
....
@ManyToOne(optional = false)
@JoinColumn(name = "po_id")
private PO po;
....
}
并且在构建 po 对象时。我在Product中设置了po字段,引用了po。
PO repo = new PO();
....
for (StockLine item: source.getStockLines()) {
Product prod = new Product();
....
prod.setPo(repo);
repo.getProducts().add(prod);
}
当我调用 PORepo.save(po);
时,它正在工作,外键被填充并且两个表中的所有数据都是正确的。
但问题是当我使用 PORepo.findAll()
获取 PO 时,我调试并发现该对象实际上是递归引用自身。
这正常吗?我觉得不正常,但我哪里做错了?
顺便说一句,如果我不添加@JsonManagedReference 和@JsonBackReference,生成的json 也将采用递归格式。上面的注解可以解决json的问题,但是返回对象的问题怎么解决呢? 我正在使用 spring boot data jpa 1.5.6.RELEASE
最佳答案
这是延迟加载的正确行为。您加载根对象并在序列化期间调用 getProducts() 。每个产品都会尝试延迟加载 PO,而 PO 又会加载产品列表等。
要打破这个链条,请引入 DTO(数据传输对象)并将您的实体转换为 TDO 对象。然后序列化 DTO。
还有一种“取消代理”实体的替代方法。参见 here
关于java - 为什么 JPA OneToMany 映射 findAll 方法返回递归对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45689894/