Как правильно сохранить сущности ManyToOne? - PullRequest
0 голосов
/ 06 марта 2020

Когда я пытаюсь сохранить свою сущность («Глава») с помощью сообщения, я получаю следующее исключение:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of "domain.Book" (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (81)

Когда я использую @JsonIgnore в поле @ManyToOne другие данные экономит нормально. Я думаю, что проблема в том, как я сохраняю «Главу», но я не знаю, как правильно ее изменить.

JSON для POST:

{
  "name": "testBookName",
  "chapters": [
    {
      "name": "testChapterName",
      "number": 1
    }
  ]
}

Результат:

{
  "id": 99,
  "book": null,
  "number": 1,
  "name": "testChapterName",
  "pages": null
}

2-й JSON вариант:

{
  "name": "testBookName",
  "id": 99,
  "chapters": [
    {
      "book": 99,
      "name": "testChapterName",
      "number": 1
    }
  ]
}

Результат:

JSON parse error: Cannot construct instance of "domain.Book" (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (99); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of "domain.Book" (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (99)\n at [Source: (PushbackInputStream); line: 6, column: 16] (through reference chain: domain.Book[\"chapters\"]->java.util.ArrayList[0]->domain.Chapter[\"book\"])"

Сущность книги:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {

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

    private String name;
    private String author;
    private String artist;
    private String year;
    private int views;
    private double rating;

    @Lob
    private String image;

    @Enumerated(EnumType.STRING)
    private Status status;

    @ElementCollection(targetClass = Genre.class, fetch = FetchType.EAGER)
    @CollectionTable(name = "genres", joinColumns = @JoinColumn(name = "book_id"))
    @Enumerated(EnumType.STRING)
    private List<Genre> genres;

    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Chapter> chapters;

}

Сущность главы:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Chapter {

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

    @ManyToOne
    @JoinColumn(name = "book_id")
    private Book book;

    private int number;

    private String name;

    @OneToMany(targetEntity = Page.class, mappedBy = "chapter", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Page> pages;

}

Сущность страницы:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Page {

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

    @ManyToOne
    @JoinColumn(name = "chapter_id")
    private Chapter chapter;

    private int number;

    @Lob
    private String image;
}

Метод контроллера для POST:

@PostMapping()
    public Chapter createChapter(@RequestBody Book book) {
        List<Chapter> chapters = book.getChapters();
        return chapterRepository.save(chapters.get(chapters.size() - 1));
    }
}

1 Ответ

0 голосов
/ 06 марта 2020

Эта проблема связана с вашим 2-м JSON вариантом

Измените JSON, чтобы оно работало.

{
 "name": "testBookName",
  "id": 99, 
  "chapters": [ 
    {
       "book": {
           "id": 99
        },
        "name": "testChapterName", 
        "number": 1
     } 
    ] 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...