1

We have this relationship:

public class RuleProviderEntity implements Serializable
{
    ...
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @OrderColumn(name = RuleEntity.RULE_SEQUENCE)
    private List<RuleEntity> rules;
}

This alone creates a join table with 2 keys and the RULE_SEQUENCE column. So far good and works for SELECTs.

Now there's a JQL query

DELETE FROM RuleProviderEntity WHERE ...

But this fails to cascade deleting the RuleEntity rows. It just deletes the RuleProviderEntity and leaves the RuleEntity intact.

Is this supposed to work in JPA 2 and it's a Hibernate bug, or am I missing something in the config?

I know I could add @JoinTable but it would only override the defaults.
Also orphanRemoval seems not necessary here.
Maybe I could do a workaround with @PreRemove but not sure how.

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277

1 Answers1

3

You mean a JPQL Bulk Delete query is issued? rather than em.remove().

A Bulk Delete query will NEVER respect cascade semantics and is not intended to (nor will it keep managed objects in-memory consistent with the datastore). If you want cascading then you need to call em.remove(). If in doubt about this look at the JPA spec.

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
  • Ok thanks. I didn't use bulk delete so far so I never knew :) But I'm quite surprised the spec doesn't require optional cascading. – Ondra Žižka Apr 27 '17 at 15:46
  • My way of thinking goes like this: There could be an entity that has the same set of `RuleEntityProvider`'s as is matched by the bulk `DELETE`. If I called `em.remove()` on that, it would cascade, and the 3rd level nested `RuleEntity` entities would also be removed. So why not cascade from the DELETE statement as well. – Ondra Žižka Apr 27 '17 at 17:01
  • Cant see why any cascading should even be optional. Bulk delete is there to do bulk operations without having to pull data from the datastore, and since "cascading" requires the JPA provider to go through all objects being deleted, work out cascades, then delete those etc, it can't be done. – Neil Stockton Apr 27 '17 at 17:04
  • There could be a shortcut - `DELETE CASCADE ... WHERE ...` would become `SELECT ... WHERE` and simply iterate over the result and do the same as `em.remove()`. Why that couldn't be done? – Ondra Žižka Apr 30 '17 at 02:08
  • because the JPA provider would have to pull objects into memory, which kinda goes against the purpose of BULK DELETE. Anyway this is what the JPA spec says, so if you want JPA to add that you go and request it of the powers that be – Neil Stockton Apr 30 '17 at 05:44
  • I am not sure if the purpose of bulk delete is not to pull objects into memory. I think the purpose is to delete multiple objects based on a condition. Whether it is including or excluding the logically nested objects is beyond being "bulk" IMO. But ok I'll suggest that to JPA committee – Ondra Žižka Apr 30 '17 at 22:51