0

Let's say there are entities like Thing and ThingItem with an 1:N relationship. Imagine that there are hundreds of items and they have some attributes which are important and tedious to set. There should be some ThingBackup gathering all changes to all items belonging to a single Thing (they get written as a blob for simplicity).

I'm doing it using hibernate listeners, so that I don't have to add code to all program parts doing the change. It works well, but I don't know how to ensure consistency.

I thought, I'd use POST_UPDATE (as opposed to POST_COMMIT_UPDATE), so that both the items and the backup get written in the same transaction.

The problem is that in a PostUpdateEventListener, doing session.createCriteria(ThingBackup.class). ... .uniqueResult() leads to a ConcurrentModificationException in hibernate. The problem seems to be that the listeners get called from a loop iterating the list of changes and this very list gets modified when accessing the database (even on a read access as it requires some flushing).

I'd call it a bug, thought it does not violate the specification (given exactly zero lines of Javadoc, there's not much to violate). It may get fixed one day or not, I need a workaround. It looks like an older version of hibernate manifested a different bug in this place.

I can create another session and use it for the needed work (read the ThingBackup, modify it and write it back). However, this way I get two transactions and, in case the one closed last fails, an inconsistency.

Is there a solution? Or am I maybe doing something wrong?

1 Answer 1

1

From the javadoc of Interceptor:

The Session may not be invoked from a callback (nor may a callback cause a collection or proxy to be lazily initialized).

The same is true for JPA entity lifecycle callbacks.

As a solution you may want to take a look at Hibernate Envers which provides auditing of entity changes.

Sign up to request clarification or add additional context in comments.

1 Comment

You're right. The documentation for events is well hidden, when you look for it. Envers uses some do-it-later-before-commit-job, which is what I did, too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.