Reputation: 487
I have a project in Java 14 with Spring Boot and Spring JPA 2.2.7.RELEASE. Let's say we have 2 entities:
PlayerEntity:
@OneToOne(mappedBy = "player", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
private GameEntity game;
GameEntity:
@JoinColumn(name = "player_id")
@OneToOne(fetch = FetchType.LAZY)
private PlayerEntity player;
I have problems with mapping, getting those entities from database and all other related operations. I get an infinite cycle, because the two entities keep on invoking themselves, like this GameEntity -> PlayerEntity -> GameEntity and so on.
The same problem I do have with DTOs and returning them as JSON (I get a "never-ending" json with these objects wrapping each other endlessly). I've figured out to mark one part of relation as @JsonIgnore, but I don't know what to do with these entities.
I would like to have access from both sides (bidirectional) and so that these objects are always filled. Is it possible without replacing actual objects with id on one/both sides? I've read some of the Spring JPA documentation and other related handbooks and according to them bidirectional relation are better than onedirectional ones, but how one could possibly achieve that with such issues on the way?
Thanks for any hints in this matter. I'd be very grateful for every tip that points me in the right direction if this pattern is possible.
EDIT:
This is actually an example for BoardEntity and GameEntity, but it's the same logic as with PlayerEntity and GameEntity. Stacktrace:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: pl.nombritech.squareconomy.model.entity.GameEntity["board"]-pl.nombritech.squareconomy.model.entity.BoardEntity["game"]-pl.nombritech.squareconomy.model.entity.GameEntity["board"]-pl.nombritech.squareconomy.model.entity.BoardEntity["game"]-pl.nombritech.squareconomy.model.entity.GameEntity["board"]-pl.nombritech.squareconomy.model.entity.BoardEntity["game"]-pl.nombritech.squareconomy.model.entity.GameEntity["board"]-
and so on...
Upvotes: 1
Views: 1247
Reputation: 111
Use
PlayerEntity:
@JsonManagedReference
@OneToOne(mappedBy = "player", cascade = CascadeType.ALL, fetch =
FetchType.LAZY, orphanRemoval = true)
private GameEntity game;
GameEntity:
@JsonBackReference
@JoinColumn(name = "player_id")
@OneToOne(fetch = FetchType.LAZY)
private PlayerEntity player;
Or vice versa.
Upvotes: 1