We've set up database cascading deletes [...]. This was considerably more efficient than doing it in JPA.
I can believe that it provided faster deletion behavior, but it was never a good idea. JPA and other ORM systems are designed and built for state management, not merely query building. Undercutting their ability to track the state they are entrusted with managing cannot reasonably be expected to end well.
This used to work fine but with Hibernate 6 we're encountering a problem.
I am prepared to believe that you did not recognize any problems with the database-level cascading deletes in conjunction with older versions of Hibernate. It might even have been that there genuinely weren't any. Nevertheless, see "cannot reasonably be expected to end well", above. Even if hadn't before, that misfortunate ending has arrived now.
If I've loaded an Child entity at some point in a test, say, then try to delete a Parent entity I get an exception
I presume you mean that you delete the particular Parent with which the Child in question is associated. The resulting DB-level cascading deletes then yank the persistent representation of the Child out from underneath the persistence unit. The persistence unit is thereby made inconsistent: the state of the Child as judged by the database is deleted / transient, but it is still persistent / managed as far as the entity manager is concerned. The best you can hope for is that the EM doesn't notice and / or doesn't care, but there is not, in general, any basis for assuming that that's what you will actually observe.
I really don't want to have to replicate the DB cascading deletes in JPA and as mention it is considerably slower than data base cascading deletes.
If Hibernate is to maintain synchronicity with the DB then there is more work to do than just removing rows from the DB. Yes, that will be more costly than allowing Hibernate to lose sync, but losing sync was never a very good option. However, you might get some relief by adding a (Hibernate-specific) @OnDelete annotation:
public class Child {
@ManyToOne(optional = false)
@JoinColumn(name = "parent")
@OnDelete(action = CASCADE)
private Parent parent
}
This tells Hibernate that there should be an on delete cascade clause on the foreign key constraint supporting the relationship. As I understand the docs, however, you would still need to use that together with JPA-level cascading removes in order for it to be effective in preventing the persistence context from losing synchronization with the DB. And I think that means you'll need to make the relationship bidirectional, though one or both ends can be lazy-loaded. Hibernate will fetch the relationship if necessary so that it knows what entities need to be evicted from its cache, but with @OnDelete, is should not execute delete statements on the database for those.
Is there a way to disable this check,
Not as far as I can tell.
or to instead flag these relationships as data-base cascading deletes
See above, but, as already described, this ...
so Hibernate knows it can just remove the entities safely?
... does not follow. Hibernate needs to know what child (and grandchild, etc) entities are deleted in order to manage its cache appropriately. That will have a cost, both in code to map the other side of the relationship and in DB operations performed, but it should be at least a bit cheaper than without the @OnDelete.