actan actan - 6 months ago 33
Java Question

Why JPA OneToMany mapping findAll method returned recursive object?

I have 2 domain classes, PO class and Product Class, and there is a List inside PO class. So Product is ManyToOne to PO, and PO is OneToMany to Product.

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;
....
}


And when building the po object. I set the po field in Product with the reference of po.

PO repo = new PO();
....
for (StockLine item: source.getStockLines()) {
Product prod = new Product();
....
prod.setPo(repo);
repo.getProducts().add(prod);
}


when I call
PORepo.save(po);
it's working, foreign key is filled and all data in both tables are correct.

But the problem is when I fetch the PO using
PORepo.findAll()
, I debugged and found the object is actually recursively reference itself.

enter image description here

Is this normal? I don't think it's normal, but where I have done wrong?

btw, if I don't add @JsonManagedReference and @JsonBackReference the generated json will be in recursive format too. The json issue can be fixed by above to annotations, but how to fix the returned object issue?
I am using spring boot data jpa 1.5.6.RELEASE

Answer Source

It's correct behavior for lazy loading. You load root object and during serializing getProducts() is called. Each of the product tries to lazyly load PO, which in turn loads list of products etc.

To break this chain introduce a DTO (Data Transfer Object) and convert your entity to TDO objects. Then serialize the DTO.

There is an alternative way to "unproxy" entity. See here

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download