在我的 Spring Boot 应用程序中,我有一个表
message
,其中有一个子表 message_recipient
,即后者拥有前者的外键。这些都使用 JPA 映射到域类。
我定义了以下 Spring Data JPA 存储库
public interface MessageRepository extends JpaRepository<Message, UUID> {
int deleteBySavedByBusinessUnitAndIdAndStatus(
BusinessUnit businessUnit, UUID messageId, MessageStatus status);
}
如果我调用此方法,
message
中的行以及message_recipient
中的关联子行将被删除。但是,如果我自己定义 JPQL 语句
public interface MessageRepository extends JpaRepository<Message, UUID> {
@Modifying
@Query("""
delete from Message m
where m.savedByBusinessUnit = :businessUnit
and m.id = :messageId
and m.status = :status""")
int deleteMessage(
BusinessUnit businessUnit, UUID messageId, MessageStatus status);
}
删除
message
中的行失败,因为 message_recipient
中存在引用该行的行。
为什么在第一种情况下删除会级联到子表,而在第二种情况下不会?有没有办法在不更改表定义(DDL)的情况下进行
deleteMessage
级联?
显式声明的查询会调用单个 SQL 查询,并且无法在 SQL 中进行级联删除。此外,此类查询不考虑实体生命周期规则,例如级联操作。
有关文档中此差异的更多信息:https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html#jpa.modifying-queries.driven-delete