我在两个实体类之间有以下双向关系:
用户
@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.hibernate
和javax.persistence
。我不想实现像@Query(Delete from User....)
这样的本机查询我想知道异常语句外键没有动作我是否直接指定了级联选项。
答案 0 :(得分:1)
Book
与User
之间存在多对一关系。因此,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