2

I am quite new to Spring. I am having a JSON parsing error when I try a POST method in Postman. Basically, I have a class that I want to call in another one in the form of a list.

I have an abstract entity that I use for classes, then I have a tag class;

@Entity
@Data
@EqualsAndHashCode(callSuper = true)
public class Tag extends AbstractEntity {

    @Column (nullable = false)
    private String tag;

And I have a question class:

@Entity
@Data
@EqualsAndHashCode(callSuper = true)
public class Question extends AbstractEntity {

    @Column (nullable = false)
    private String title;
    @Column (nullable = false)
    private String content;
    @OneToMany
    @Column (nullable = false)
    private List<Tag> tag;

Here is my controller:

@RestController
@RequestMapping("v1/enquiry")
public class EnquiryController {

    @Autowired
    private QuestionRepository questionRepository;

    @PostMapping
    public ResponseEntity<Question> createEnquiry(@RequestBody Question question) {
        if (question.getTitle() == null | question.getContent() == null) {
            throw new BadRequest("Please fill in the required fields!");
        }

        Question enq = questionRepository.save(question);
        return ResponseEntity.ok().body(enq);
    }

When I do a POST method with:

{ 
   "title": "question",
   "content": "cogito",
   "tag": ["java", "rest"]
}

I get the following error. I quite tried all of the suggestions to similar conditions posted around. None of them worked. What am I doing wrong?

"message": "JSON parse error: Cannot construct instance of com.mockup.mockupapi.model.Tag (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('java'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of com.mockup.mockupapi.model.Tag (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('java')\n at [Source: (PushbackInputStream); line: 4, column: 10] (through reference chain: com.mockup.mockupapi.model.Question[\"tag\"]->java.util.ArrayList[0])",


SOLVED

Thanks to clues in the commentary, I changed the array format in JSON, and added CascadeType to OneToMany call. I used .PERSIST, however, .ALL works as well.

The JSON format:

{ 
   "title": "question",
   "content": "cogito",
   "tag": [{"tag":"java"},{"tag": "rest"}]
}

The Question class:

@Entity
@Data
@EqualsAndHashCode(callSuper = true)
public class Question extends AbstractEntity {

    @Column (nullable = false)
    private String title;
    @Column (nullable = false)
    private String content;
    @OneToMany(cascade = CascadeType.PERSIST)
    @Column (nullable = false)
    private List<Tag> tag;
7
  • What happens if you add a @NoArgsConstructor to Tag? Commented Feb 15, 2020 at 2:10
  • I tried, however, I still get the same error, with the same message output. @user991710 Commented Feb 15, 2020 at 9:00
  • Change your JSON to this "tag":[{"tag":"java"},{"tag":"rest"}]. Specifically for that tag key. Commented Feb 15, 2020 at 9:06
  • I actually tried versions like "tag":{"java","rest"} and other possible versions. However, this one throws a IllegalStateException error: save the transient instance before flushing. @gnanajeyam95 Commented Feb 15, 2020 at 9:16
  • Then add cascade type to ur one to many mapping Commented Feb 15, 2020 at 9:18

1 Answer 1

2

Please change your JSON structure.

{ "title": "question", "content": "cogito", "tag": [{"tag":"java"},{"tag": "rest"}] }

Also add cascade in your mapping.

@OneToMany (cascade = CascadeType.ALL)
 @Column (nullable = false) 
 private List<Tag> tag;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.