I am using ManyToOne , OneToMany and have endless loop when getting data

你离开我真会死。 提交于 2020-08-07 05:55:31

问题


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

  1. First approach is to create custom DTOs and return them from your rest controller. In the DTOs, you will populate the location field of the customerDto with locationDtos but you will NOT set the customer field of locationDto and it will be null.

  2. Second approach is less preferred. But we can tell the Jackson library to not to serialise it recursively by adding @JsonManagedReference and @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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!