java - Hibernate - JPA - OneToMany 和 CascadeType.ALL

标签 java spring hibernate jpa cascade

我有一个关于@OneToMany 的 JPA 问题,特别是关于 CascadeType.ALL 的功能。 我有两个实体,一个父亲和一个 child 。

我给你举个例子: 预订

@Entity
@Table(name = "books")
public class Book implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    @JoinColumn(name="id_page")
    private List<Page> pages;
    ...
    ...
}

页数

@Entity
@Table(name = "pages")
public class Page implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;

    @Column(name = "id_book")
    private int idBook;
    ...
    ...
}

所以,我只有一本书和几页。当我保存这本书时,我也保存了其中包含的页面,这要归功于 CascadeType.ALL。 这行得通,实际上 Hibernate 尝试保存 Book 对象,通过 OneToMany 意识到还有要保存的 Page 实体,并通过 Cascade ALL 启动查询。

我只是这样做:

bookRepository.save(book);

代表我要保存的书的 json 是这样的:

{
  "id": 0,
  "page": [
    {
      "id": 0,
      "idBook": 0
    }
  ]
}

但是,如果我将 0 放入图书 ID,它就会被创建。如果我将 idBook 上的 0 放入页面,它会给我这样的错误:Key (id_book) = (0) is not present in table "book"。

但是,我真正不明白的是:为什么如果我将 id_book 放入存在于数据库中的 json 中,然后完成保存书籍实体,它会理解 id 是什么并将其正确插入数据库中?

所以,如果我给这个 JSON。

{
  "id": 0,
  "page": [
    {
      "id": 0,
      "idBook": 1
    }
  ]
}

让我们考虑在数据库中只有一本 id=1 的书。 保存后,它会为我生成一行 id=2 的书,以及一个链接到 id=2 的书的页面?

这件事让我发疯。 如果给一个 idBook = 0 告诉他他必须检索/生成它,他告诉我它不存在。另一方面,如果我给他一个真实存在的 idBook(但它不正确),他会不会考虑并正确使用他刚创建的 Book 的 idBook?

我只想不必使用伪造的 idBook,告诉他他必须在创建书籍后获取页面 idBook,就像他实际做的那样。

最佳答案

根据 Page 实体中的 id_book 列,我得出结论,您希望使用双向映射。尝试这样做,将 child 作为关系的主人:

@Entity
@Table(name = "pages")
public class Page implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;

    @ManyToOne(fetch = FetchType.LAZY) // EAGER by default
    @JoinColumn(name = "id_book")
    private Book book;
    ...
    ...
}
@Entity
@Table(name = "books")
public class Book implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL) // Lazy fetch type by default
    private List<Page> pages = new ArrayList<>();
    ...
    ...
    
    // obligatory synchronization methods
    public void addPage(Page page) {
        pages.add(page);
        page.setBook(this);
    }

    public void removePage(Page page) {
        pages.remove(this);
        page.setBook(null);
    }
}

关于java - Hibernate - JPA - OneToMany 和 CascadeType.ALL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63620679/

相关文章:

java - Netbeans 6.9.1 中的 BPEL 组合 Web 服务

使用 JSON 和 JSP 的 Spring MVC Controller

java - 在 springdoc-openapi-ui 中启用“授权”按钮以进行不记名 token 身份验证 (JWT)

java - 在 Native SQL Hibernate 中使用 addJoin

java - 如何记录hibernate native SQL而不是HQL?

java - Netbeans 平台 : InstalledFileLocator

java - Spring Boot 管理客户端无法构建

java - intellij 导入现有的 eclipse android 项目失败

java - Hibernate 4 Spring 4 无法获取当前线程的事务同步 session

java - 以最快的方式将大量数据从vertcicadb表批量加载到mysql表