java - 如何正确保存ManyToOne实体?

标签 java hibernate spring-boot jpa

当我尝试用帖子保存我的实体(“章节”)时,我收到此异常:

org.springframework.http.converter.HttpMessageNotReadableException:JSON解析错误:无法构造“domain.Book”的实例(尽管至少存在一个创建者):没有要反序列化的int/Int参数构造函数/工厂方法来自数值 (81)

当我在 @ManyToOne 字段上使用 @JsonIgnore 时,其他数据保存得很好。 我认为问题出在我保存“章节”的方式上,但我不知道如何将其更改为正确的方式。

POST 的 JSON:

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

结果:

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

第二个 JSON 变体:

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

结果:

JSON 解析错误:无法构造“domain.Book”的实例(尽管至少存在一个 Creator):没有用于从数值 (99) 反序列化的 int/Int 参数构造函数/工厂方法;嵌套异常是 com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造“domain.Book”的实例(尽管至少存在一个 Creator):没有从 Number 值(99 )\n 在 [来源:(PushbackInputStream);行:6,列:16](通过引用链: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 Controller 方法:

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

最佳答案

此问题与您的第二个 JSON 变体有关

将您的 JSON 更改为这样就可以了。

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

关于java - 如何正确保存ManyToOne实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60569697/

相关文章:

java - 将路径点添加到 Google map Intent (Android)

hibernate - 为什么我在使用 Hibernate 时会在简单的 "get"中收到错误?

java - @RequestParam 带 swagger ui 注释的方法不显示描述

java - 如何使用 Spring Data 从 Mongo 文档的数组字段中仅获取匹配结果

java - Spring Boot 和@ConfigurationProperties

java - 测试失败后如何强制maven执行下一个目标

java - 此Java正则表达式如何检测回文?

java - Spring MVC 示例中的 "Hello World"来自哪里

hibernate - 对旧数据库使用Grails/Hibernate。如何创建缺少的功能?

java - @SequenceGenerator 在用@MappedSuperclass 注释的类上