Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.0k views
in Technique[技术] by (71.8m points)

java - Sending JSON data over post man giving the Failed to evaluate Jackson deserialization for type in Spring Boot Jpa project

Course.java

package com.example.jpa_training.JPAD.model;

@Entity
@Table(name = "COURSE")
public class Course implements Serializable{

    public Course() {}


    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    private String name;
    private String description;


    @ManyToOne(targetEntity=Department.class)
    @JsonIgnore
    private Department department;

    @ManyToMany(mappedBy="courses", targetEntity=Student.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JsonIgnore
    private Set<Student> students = new HashSet<Student>();


    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name="professor_id")
    @JsonManagedReference
    private Professor professor;

    
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    
    
    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }
    
    
    
    
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
    
    
    
    
    public Professor getProfessor() {
        return professor;
    }

    public void setProfessor(Professor professor) {
        this.professor = professor;
    }

    
    
    
    
    public Set<Student> getStudents() {
        return students;
    }


    public void addStudent(Student student) {
        this.students.add(student);
        
    }
    
    public void removeStudent(Student student) {
        this.students.remove(student);
    }
    
    @OneToMany(mappedBy = "course", fetch = FetchType.LAZY)
    private Set<Review> reviews;
}
    

Review.java

@Entity
public class Review implements Serializable{

    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long reviewId;
    
    @ManyToOne
    private Course course;
    
    private String reviewDescription;
    
    private double courseRating;

    
    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public String getReviewDescription() {
        return reviewDescription;
    }

    public void setReviewDescription(String reviewDescription) {
        this.reviewDescription = reviewDescription;
    }

    public double getCourseRating() {
        return courseRating;
    }

    public void setCourseRating(double courseRating) {
        this.courseRating = courseRating;
    }
}

Postman Input

{
    "course": {
        "id": 4,
        "name": "Data Analysis",
        "description": "Just take it",
        "professor": {
            "name": "Kapil Dev",
            "qualification": "M.Tech",
            "department": {
                "deptId": 1,
                "deptName": "Big Data",
                "buildingName": "DS-04"
            }
        }
    },
    "reviewDescription": "Good course, nice teaching",
    "courseRating": 0.0
}

Error Log

Failed to evaluate Jackson deserialization for type [[simple type, class com.example.jpa_training.JPAD.model.Review]]: com.fasterxml.jackson.databind.JsonMappingException: 2020-12-30 11:45:00.869 WARN 11152 --- [nio-8080-exec-2] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class com.example.jpa_training.JPAD.model.Review]]: com.fasterxml.jackson.databind.JsonMappingException: 2020-12-30 11:45:00.869 WARN 11152 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported]

Tried solutions

Using @JsonBackReference and @JsonManagedReference Using @JsonIdentityInfo and @JsonIgnore but the error is the same I can save and retrieve the data from Java but when I send data over postman or using curl command I get the above error, I tried many ways but couldn't fix it


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I wouldn't suggest exposing entities directly to your controller. Entities should only contain JPA annotations in your case. You can expose a DTO (Data Transfer Object) to your controller and then map the DTO to the corresponding entity.

ReviewDto

public class ReviewDto {
    private String reviewDescription;

    private double courseRating;

    private CourseDto course;

    // getters, setters, etc
}

CourseDto

public class CourseDto {
    private Long id;

    private String name;

    private String description;

    // professorDto, getters, setters, etc
}

An example demonstrating how your controller class will be

@RestController
public class DemoController {
    private final ReviewDtoMapper reviewDtoMapper;
    private final ReviewService reviewService;

    public DemoController(ReviewDtoMapper reviewDtoMapper,
                          ReviewService reviewService) {
        this.reviewDtoMapper = reviewDtoMapper;
        this.reviewService = reviewService;
    }

    @PostMapping(value = "demo")
    public ResponseEntity<String> postReview(@RequestBody ReviewDto reviewDto) {
        final Review review = reviewDtoMapper.mapFrom(reviewDto);

        reviewService.save(review);

        return ResponseEntity.ok("");
    }
}

The class to map from reviewDto to review entity and the opposite.

@Component
public class ReviewDtoMapper {

    public ReviewDto mapTo(final Review entity) {

        ReviewDto reviewDto = new ReviewDto();
        reviewDto.setReviewDescription(entity.getReviewDescription());
        // set all the properties you want
        return reviewDto;
    }


    public Review mapFrom(ReviewDto dto) {

        Review review = new Review();
        review.setReviewDescription(dto.getReviewDescription());
        // set all the properties you want
        return review;
    }
}

Of course, you have to make adjustments according to your needs.

If you like this way of doing things I would suggest you check MapStruct, it will automatically make the mappers for you.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...