| Session#refresh method seems to be inconsistent with how it handles cascading into parent/child collections. There is a mention in the documentation, section 5.11.1 refresh gotchas, about the problem with handling transient entities. However there is nothing said about refreshing deleted/new entities that were deleted/added behind the session's back. The actual behavior is quite inconsistent:
- If a child was deleted, then refresh will fail with EntityNotFoundException exception and current transaction will be marked for rollback.
- If a child was added, then refresh will succeed and the new child will appear in the collection
- If there was a mix of additions and deletions, then refresh will fail with EntityNotFoundException exception
I've created a unit test that shows all the 3 cases. The problem seems to appear frequently in online discussions with evict being suggested as solution. There is also HHH-2305 Closed which was reported a while back but was closed due to lack of activity. I think a simpler solution would be to prevent refresh cascading into collections and just reload collections as it is already done by Hibernate in the second case. The solution looks like this: {{ public static final CascadeStyle ALL_DELETE_ORPHAN = new BaseCascadeStyle() { @Override public boolean doCascade(CascadingAction action) { return action != CascadingActions.REFRESH; } }} |