问题
I am using ManyToOne and OneToMany in hibernate .I want to create a user who has locations. When I get data in postman I have endless loop because when I get user it's showing a user's location and in location showing user and so on. Here is code:
Locations class :
@ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name=FLD_LOC, nullable=false)
private Consumer consumers;
public Consumption(String location, float consumpiton,Consumer consumer) {
this.location = location;
this.consumpiton = consumpiton;
this.consumers=consumer;
}
User class :
@OneToMany(mappedBy = Consumption.FLD_LOC,orphanRemoval = true)
private List<Consumption> locations ;
public Consumer(String clientId, String name,String location, float pwConsumption, String email, String password, String roles) {
super(clientId, name, email, password, roles);
this.locations=new ArrayList<>();
this.location=location;
this.pwcons=pwConsumption;
}
But in database it's storing name of location in users table and id of user in locations table
Here is problem looks like :
"id": 2,
"version": 1,
"updated": "2020-06-28T15:41:49.082",
"clientId": "admin",
"name": "admin",
"email": "admin123@gmail.com",
"password": "$2a$10$hgcTSHjGpxEPg6WNb0U7ouHR5J5YYR5l1XVAejdK8JsG9w2Bko00a",
"active": true,
"roles": "ROLE_ADMIN",
"locations": [
{
"locationsid": 1,
"location": "Pecs",
"consumpiton": 0.0,
"consumers": {
"id": 2,
"version": 1,
"updated": "2020-06-28T15:41:49.082",
"clientId": "admin",
"name": "admin",
"email": "admin123@gmail.com",
"password": "$2a$10$hgcTSHjGpxEPg6WNb0U7ouHR5J5YYR5l1XVAejdK8JsG9w2Bko00a",
"active": true,
"roles": "ROLE_ADMIN",
"locations": [
{
"locationsid": 1,
"location": "Pecs",
"consumpiton": 0.0,
"consumers": {
"id": 2,
"version": 1,
"updated": "2020-06-28T15:41:49.082",
"clientId": "admin",
"name": "admin",
"email": "admin123@gmail.com",
"password": "$2a$10$hgcTSHjGpxEPg6WNb0U7ouHR5J5YYR5l1XVAejdK8JsG9w2Bko00a",
"active": true,
"roles": "ROLE_ADMIN",
"locations": [
{
"locationsid": 1,
"location": "Pecs",
How to let it show in JSON Locations part only name of location or id?
回答1:
Problem
This is generic issue when you have to serialise objects with bidirectional relationship.
Solution
Signal the serialiser where to stop when facing bidirectional relationship
First approach is to create custom DTOs and return them from your rest controller. In the DTOs, you will populate the
locationfield of thecustomerDtowithlocationDtos but you will NOT set thecustomerfield oflocationDtoand it will be null.Second approach is less preferred. But we can tell the Jackson library to not to serialise it recursively by adding
@JsonManagedReferenceand@JsonBackReference.
- Replace
@OneToMany(mappedBy = Consumption.FLD_LOC,orphanRemoval = true)
private List<Consumption> locations ;
with
@OneToMany(mappedBy = Consumption.FLD_LOC,orphanRemoval = true)
@JsonManagedReference
private List<Consumption> locations ;
- Replace
@ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name=FLD_LOC, nullable=false)
private Consumer consumers;
with
@ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name=FLD_LOC, nullable=false)
@JsonBackReference
private Consumer consumers;
Note:
In production systems, we don't expose all the fields of domain objects as it can have many internal fields which should not be exposed to outside. It is the reason, first approach is preferred
来源:https://stackoverflow.com/questions/62623483/i-am-using-manytoone-onetomany-and-have-endless-loop-when-getting-data