0

I need to delete an entity with its children entities. Here is my code :

public void deleteCascade(Integer entityId) {
  CriteriaBuilder cb = em.getCriteriaBuilder();
  CriteriaDelete<MyEntity> criteriaDelete = cb.createCriteriaDelete(MyEntity.class);
  Root<MyEntity> myEntity = criteriaDelete.from(MyEntity.class);
  criteriaDelete.where(
          cb.equal(MyEntity.get(MyEntity_.id), entityId)
  );
  em.createQuery(criteriaDelete).executeUpdate();
}

This will obviously not work because of orphans. I know 2 solutions which do not statisfy me :

  • Manually delete orphans, one request per entity.
  • Anotate the entity attributes.

I would actually prefer using a simple parameter somewhere but cannot find if it exists.

Any idea?

Arnaud Denoyelle
  • 29,980
  • 16
  • 92
  • 148
  • Do you use some more expressions in your where statement, or why don't you use `EntityManager.remove()`? And with _annotate the entity attributes_ you mean `cascade=...`? – Tobias Liefke Jun 22 '15 at 13:03
  • @TobiasLiefke Yes, I could use `EntityManager.remove()`, And yes, I mean `cascade = ...`. In order to have the code working, I will use the annotation but I would appreciate if a cleaner method existed. – Arnaud Denoyelle Jun 22 '15 at 13:32
  • I think that `cascade=CascadeType.REMOVE` (or `CascadeType.ALL`) is the best solution, as it describes the relationship where it belongs to: in the model. Otherwise it is easy to forget to delete the orphans when you (or one of your collaborators) delete a `MyEntity`. – Tobias Liefke Jun 23 '15 at 07:53

1 Answers1

0
  • Solution 1. With two queries:

    1. Delete ALL future orphans (i.e BULK DELETE, not a query per entity).
    2. Delete the entity itself.
  • Solution 2: I am not sure it is not the same as your second idea: Mark the relationship with orphanRemoval=true

V G
  • 18,822
  • 6
  • 51
  • 89
  • `orphanRemoval` is _not_ working for the given example: `orphanRemoval` means to remove a child from a database, when its reference is removed, while `cascade=CascadeType.REMOVE` means to delete it, if the parent entity is deleted. – Tobias Liefke Jun 23 '15 at 07:44
  • `orpahnRemoval` [means](http://stackoverflow.com/questions/27621433/jpa-cascadetype-all-doesnt-delete-parent-and-child-rows) to delete the parent WITH its children. I think it should also work. What about the first solution? – V G Jun 23 '15 at 07:59
  • I think [this question](http://stackoverflow.com/questions/4329577/jpa-2-0-orphanremoval-true-vs-on-delete-cascade) would have been better to describe the difference between both annotations. But you are right, it would work - except that it does more than the op needed. I have nothing against your first solution - although I think the annotation is the better solution (see my comment on the op). – Tobias Liefke Jun 23 '15 at 08:09
  • The question you linked in your comment explains the difference between JPA's `orphanRemoval` and `ON DELETE CASCADE` that is implemented on DB level (eg. [MySql](http://www.mysqltutorial.org/mysql-on-delete-cascade/)). As I understand, OP needs to delete the parent along with its children, what `orphanRemoval` also does. – V G Jun 23 '15 at 09:29