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 ofcom.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;
@NoArgsConstructor
toTag
? – user991710"tag":{"java","rest"}
and other possible versions. However, this one throws aIllegalStateException
error:save the transient instance before flushing
. @gnanajeyam95 – emrahyergin