使用Spring Data JPA(双向)删除级联

时间:2016-07-25 07:51:39

标签: spring hibernate jpa spring-data-jpa

我在两个实体类之间有以下双向关系:

  

用户

@Entity
@Table(name = "USER")
public class User {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    @Cascade({CascadeType.REMOVE, CascadeType.SAVE_UPDATE})
    private Set<Book> books;
}
  

图书

@Entity
@Table(name = "BOOKS")
public class Book {
    @ManyToOne(optional = false)
    @JoinColumns({
            @JoinColumn(name = "ID", referencedColumnName = "ID"),
            @JoinColumn(name = "NAME", referencedColumnName = "NAME"),
    })
    private User user;

}

我想删除User,删除级联到与用户关联的所有图书。但是,当我使用Spring Data CrudRepository

myDAO.delete(String userId) // interface extending CrudRepository<User, UserPK>

我得到了:

Caused by: org.hsqldb.HsqlException: integrity constraint violation: foreign key no action; FK_IN88FEHUXOOYQK0YE71USPIEP table: USER

我尝试使用orhpanRemoval,所有CascadeTypes org.hibernatejavax.persistence。我不想实现像@Query(Delete from User....)这样的本机查询我想知道异常语句外键没有动作我是否直接指定了级联选项。

1 个答案:

答案 0 :(得分:1)

BookUser之间存在多对一关系。因此,Book表只需要一列来捕获User表的外键。

代码:

@ManyToOne(optional = false)
@JoinColumns({
        @JoinColumn(name = "ID", referencedColumnName = "ID"),
        @JoinColumn(name = "NAME", referencedColumnName = "NAME"),
})
private User user;

应该只是:

@ManyToOne(optional = false)
@JoinColumn(name = "user_id")
private User user;

使用Hibernate模式生成工具(HBM2DDL)时,将生成外键约束,如下所示:

ALTER TABLE
  BOOK
ADD CONSTRAINT
  FK_IN88FEHUXOOYQK0YE71USPIEP
FOREIGN KEY
  (USER_ID) REFERENCES USER (ID)
ON UPDATE NO ACTION
ON DELETE NO ACTION;

注意ON DELETE NO ACTION。这意味着,当删除User实例时,与Book实例关联的NO ACTION实例不会发生任何事情(User)。这实际上意味着不应该删除Book

如果您希望在删除User时删除与User关联的ALTER TABLE BOOK ADD CONSTRAINT FK_IN88FEHUXOOYQK0YE71USPIEP FOREIGN KEY (USER_ID) REFERENCES USER (ID) ON UPDATE NO ACTION ON DELETE CASCADE; 个实例,则DDL应为:

class User {
  @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
  @Cascade({CascadeType.REMOVE, CascadeType.SAVE_UPDATE})
  @OnDelete(OnDeleteAction.CASCADE)
  private Set<Book> books;
}

这可以通过向域模型添加特定于Hibernate的注释来生成:

method_decorator