【问题标题】:Primary key of Parent Entity not stored as Foreign Key in Child Entity父实体的主键未在子实体中存储为外键
【发布时间】:2019-09-06 01:11:23
【问题描述】:

我在 Spring Data Jpa 中使用 OneToMany 关系并使用 postMan 测试 api

@Entity
@Table(name = "book_category")
public class BookCategory {
ParentEntity
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "bookCat_id")
    private Long id;

    private String name;

    @OneToMany(cascade = CascadeType.ALL, mappedBy="bookCategory")
    private Set<Book> books;

    public BookCategory(String name, Set<Book> books) {
        this.name = name;
        this.books = books;
    }

// getter and setter

}

ChildEntity


    @Entity
    @Table(name = "book")
    public class Book {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "book_id")
        private Long bookId;

        private String name;

        @ManyToOne(cascade = CascadeType.PERSIST)
        @JoinColumn(name = "bookCat_id")
        BookCategory bookCategory;

        public Book() {

        }

    //getter  and Setter

    }

控制器类

@RestController
@RequestMapping(value = "/bookCategory")
public class BookController {

    @Autowired
    BookCategoryRepository bookCategoryRepository;

    @Autowired
    BookRepository bookRepository;

    @PostMapping("/addBookCategory")
    public BookCategory savePerson(@Valid @RequestBody BookCategory bookCategory){
        return bookCategoryRepository.save(bookCategory);
    }
}

从邮递员调用 Rest Api 并将 json 传递为

{

    "name":"Category 1",
    "books":[
          {"name" : "Hello Koding 1"},
          {"name":"Hello Koding 2"}
        ]
} 

以下查询是由休眠执行的查询也是正确的,而我正在调用休息点的东西 Hibernate:插入 book_category(名称)值(?) Hibernate:插入书(book_cat_id,name)值(?,?)

它没有插入 book_cat_id,在 book_cat_id 中它传递了 null 所以 null 正在存储

存储在数据库中的数据 book_category Parent Table in database

书(子表) book(ChildTable) 我想得到 Child Table Like I want my table like this

【问题讨论】:

  • 如果在您的 db book 表中它被声明为 fk,那么只需在您的 book 实体中使用 book category id 而不是 object。

标签: java spring spring-boot spring-data-jpa


【解决方案1】:

问题是您没有在子对象中设置父对象。您应该在代码中的某处调用

public void setBookCategory(BookCategory bookCategory) { ... }

Book 实体的方法。

我建议通过在控制器中使用 DTO 并将它们映射到服务层中的实体来解决此问题,因为使用永久实体作为 http 请求的参数可能会导致严重的安全漏洞,如 here 所述。

编辑:或者,即使我不鼓励这种解决方案,也可以像这样修改 savePerson 方法

@PostMapping("/addBookCategory")
public BookCategory savePerson(@Valid @RequestBody BookCategory bookCategory){
    bookCategory.getBooks().forEach(book -> book.setBookCategory(bookCategory));
    return bookCategoryRepository.save(bookCategory);
}

【讨论】:

  • public void setBookCategory(BookCategory bookCategory) { ... } 这是 getter/setter 的一部分 在我调用休息点时正在执行以下查询 Hibernate: insert into book_category (name) values (? ) Hibernate: 插入书 (book_cat_id, name) 值 (?, ?) 它没有插入 book_cat_id,在 book_cat_id 它传递 null 所以 null 正在存储
  • Hibernate 在 book_cat_id 中插入空值,因为 setBookCategory 方法已实现,但从未调用。在 savePerson 方法中下断点,你会发现 BookCategory 中的 Books 没有父级(Book 实体中的 BookCategory 将为空)。
  • 那有什么解决办法
  • 数据保存在 db 中但出现类似这样的 gitving 错误 "status":200,"error":"OK","message":"Could not write JSON: Infinite recursion (StackOverflowError); 嵌套例外是 com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (通过参考链: com.abhinash.restapi.entities.OneToMany.BookCategory[\"books\"] 你能告诉我为什么我得到这个错误*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
  • @Abhinash 我可以为您指出正确的方向 - stackoverflow.com/a/18288939/3750108 您现在面临的问题有一个解决方案。
猜你喜欢
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 2021-12-21
相关资源
最近更新 更多