Pergunta

I have following problem: when I try to delete an entity that has following relation:

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

with a CrudRepository through a provided delete method it removes the entity along with its all chargeable elements which is fine. The problem appears when I try to use my custom delete:

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

it says:

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`))

Why I am not allowed to do this? Does @Query methods do not support cascade property? I know I can findByListkeyId(…) first and then remove persistent entity with standard delete method, but it is inelegant. Is it possible to use a custom @Query method the way I tried to?

Foi útil?

Solução

This has got nothing to do with Spring Data JPA but is the way JPA specifies this to work (section 4.10 - "Bulk Update and Delete Operations", JPA 2.0 specification):

A delete operation only applies to entities of the specified class and its subclasses. It does not cascade to related entities.

If you think about it, JPA cascades are not database-level cascades but ones maintained by the EntityManager. Hence, the EntityManager needs to know about the entity instance to be deleted and its related instances. If you trigger a query, it effectively can't know about those as the persistence provider translates it into SQL and executes it. So there's no way the EntityManager can analyze the object graph as the execution is completely happening in the database.

A question and answer related to this topic here can be found over here.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top