Jackson failed to deserialization OneToMany objects

16,404

Solution 1

You could add @JsonBackReference to the other site of the relation. Which by the way is missing or not correct implemented. Add:

@JsonBackReference
@ManyToOne
@JoinColumn(name = "autoServiceId", nullable = false)
private AutoService autoService;

instead of private long autoServiceId;.

Also the AutoService needs to be adjusted with:

@JsonManagedReference
@OneToMany(mappedBy = "autoService", fetch=FetchType.EAGER)
private List<Service> services = new ArrayList<>();

Solution 2

Solution #1 : - add @JsonIgnore where you have attributes with @OneToMany Example:

class User {
    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JsonManagedReference
    @JsonIgnore
    private List<Comment> comments;
}

class Comment {
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id")
    @JsonBackReference
    private User user;
}

Solution #2: - use on your class @JsonIgnoreProperties({"name-of-your-attribute"}), for example "comments"

Share:
16,404
Andrew
Author by

Andrew

Updated on June 04, 2022

Comments

  • Andrew
    Andrew almost 2 years

    I have faced with the problem that converter can't handle JSON object.

    I have two objects in data base. Relationship OneToMany.

    I have a AutoService with many services.

    And wnen i am trying to send JSON object using postman to my server - I am getting an error:

    WARN org.springframework.http.converter.json.MappingJackson2HttpMessageConverter - Failed to evaluate Jackson deserialization for type [[simple type, class com.webserverconfig.user.entity.AutoService]]: java.lang.IllegalArgumentException: Can not handle managed/back reference 'defaultReference': no back reference property found from type [collection type; class java.util.List, contains [simple type, class com.webserverconfig.user.entity.Service]]
    

    Next two classes represents my model:

    Class AutoService:

    @Entity
    @Table(name = "AutoRate")
    public class AutoService {
    
        public AutoService() {
        }
    
        @Id
        @GeneratedValue(generator = "increment")
        @GenericGenerator(name = "increment", strategy = "increment")
        private long id;
    
        @Column(name = "serviceName", nullable = false)
        private String serviceName;
    
        @Column(name = "imageURL", nullable = false)
        private String imageURL;
    
        @Column(name = "mapCoordinate", nullable = false)
        private String mapCoordinate;
    
        @Column(name = "websiteURL", nullable = false)
        private String websiteURL;
    
        @Column(name = "phoneNumber", nullable = false)
        private String phoneNumber;
    
        @JsonManagedReference
        @OneToMany(fetch = FetchType.EAGER)
        @JoinColumn(name = "autoServiceId")
        private List<Service> services;
    
        public long getId() {
            return id;
        }
    
        public String getServiceName() {
            return serviceName;
        }
    
        public String getImageURL() {
            return imageURL;
        }
    
        public String getMapCoordinate() {
            return mapCoordinate;
        }
    
        public String getWebsiteURL() {
            return websiteURL;
        }
    
        public String getPhoneNumber() {
            return phoneNumber;
        }
    
        public List<Service> getServices() {
            return services;
        }
    }
    

    Class service:

    @Entity
    @Table(name = "Service")
    public class Service {
    
        public Service() {
        }
    
        @Id
        @GeneratedValue(generator = "increment")
        @GenericGenerator(name = "increment", strategy = "increment")
        @Column(name = "serviceId", unique = true, nullable = false)
        private long serviceId;
    
        @Column(name = "serviceName", nullable = false)
        private String serviceName;
    
        @Column(name = "category", nullable = false)
        private String category;
    
        @Column(name = "price", nullable = false)
        private int price;
    
        @Column(name = "autoServiceId", nullable = false)
        private long autoServiceId;
    
        public long getId() {
            return serviceId;
        }
    
        public String getCategory() {
            return category;
        }
    
    
        public int getPrice() {
            return price;
        }
    
        public String getServiceName() {
            return serviceName;
        }
    
        public long getAutoServiceId() {
            return autoServiceId;
        }
    }
    

    Asking for help. Am i missing some annotation ?

    Also Controller class:

    @RestController
    @RequestMapping("/directory")
    public class ServiceController {
    
        @Autowired
        private AutoRateService dataBaseService;
    
        @RequestMapping(value = "/get", method = RequestMethod.GET)
        @ResponseBody
        public AutoService getData(){
            AutoService dataList = dataBaseService.getById(1);
            return dataList;
        }
    
        @RequestMapping(value = "/saveService", method = RequestMethod.POST)
        @ResponseBody public AutoService saveAutoService(@RequestBody AutoService autoService){
            return dataBaseService.save(autoService);
        }
    }