Issue
I have entities that have references to themselves, for example:
Client
has manyProperties
Property
has manyClients
Returning list of Properties
by Client
id causes StackOverflowError
because it keeps nesting Properties
inside Client
and so on.
How can I deal with nesting in the most proper / elegant way?
Service
public Set<Home> getHouses(Long userId) {
return Utils.iterableToCollection(((HomeRepository) (getRepository())).findAll(), HashSet::new);
}
Controller
@GetMapping("/all")
@ResponseBody
public GenericResponse getHouses(@RequestParam("id") Long userId) {
Set<Home> houses = homeService.getHouses(userId);
return new GenericResponse(
"houses fetched successfully",
houses,
HttpStatus.OK
);
}
Home
public class Home extends AbstractEntity<Long> {
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "homeAddress_id")
private Address address;
@ManyToMany(mappedBy = "properties", fetch = FetchType.EAGER)
private Set<Client> clients = new HashSet<>();
@Lob
private byte[] apartmentPicture;
}
Client
public class Client extends User {
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "CLIENT_HOME",
joinColumns = @JoinColumn(name = "client_id"),
inverseJoinColumns = @JoinColumn(name = "home_id")
)
private Set<Home> properties = new HashSet<>();
}
Solution
If you use Jackson 2.6+
, you can use @JsonProperty(access = Access.WRITE_ONLY)
on the property you don't want to serialize. So if you want to include the clients when you fetch your houses, put it on the properties
field in your Client
class, which will simply ignore that field during serialization. However, I would advise you to decouple your database layer from your representation layer and map every entity to a DTO, that helps you a lot in the long run.
You can read more about the JsonProperty
annotation here.
Answered By - Krisz
Answer Checked By - Candace Johnson (JavaFixing Volunteer)