为什么手动定义的Spring Data JPA删除查询不会触发级联?

Pio*_*pes 1 jpa cascade jpql cascading-deletes spring-data-jpa

我有以下问题:当我尝试删除具有以下关系的实体时:

@OneToMany(mappedBy="pricingScheme", cascade=CascadeType.ALL, orphanRemoval=true)
private Collection<ChargeableElement> chargeableElements;
Run Code Online (Sandbox Code Playgroud)

CrudRepository通过提供删除方法它消除其所有的充电元件,其是精细沿着实体。当我尝试使用自定义删除时出现问题:

@Modifying
@Query("DELETE FROM PricingScheme p WHERE p.listkeyId = :listkeyId")
void deleteByListkeyId(@Param("listkeyId") Integer listkeyId);
Run Code Online (Sandbox Code Playgroud)

它说:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
  Cannot delete or update a parent row: a foreign key constraint fails
  (`listkey`.`chargeableelements`, CONSTRAINT `FK_pox231t1sfhadv3vy7ahsc1wt` 
  FOREIGN KEY (`pricingScheme_id`) REFERENCES `pricingschemes` (`id`))
Run Code Online (Sandbox Code Playgroud)

为什么不允许我这样做?难道@Query方法不支持级联特性?我知道我可以findByListkeyId(…)先使用标准的delete方法删除持久性实体,但这是不雅致的。是否可以@Query按照我尝试的方式使用自定义方法?

Oli*_*ohm 5

这与Spring Data JPA无关,而是JPA指定它起作用的方式(第4.10节-“批量更新和删除操作”,JPA 2.0规范):

删除操作仅适用于指定类及其子类的实体。它不会级联到相关实体。

如果您考虑一下,JPA级联不是数据库级级联,而是由维护的级联EntityManager。因此,EntityManager需要知道要删除的实体实例及其相关实例。如果您触发查询,则持久化提供程序会将其转换为SQL并执行该查询,从而实际上无法得知这些查询。因此EntityManager,由于执行完全在数据库中进行,因此无法分析对象图。

此主题相关这里的一个问题和答案都可以找到这里了