Hibernate’s event system

So I just had an interesting realization, Hibernate uses various default listeners in it’s poorly documented event system to do all of its persistence work.

For example, saving an object through a Hibernate Session object quickly goes to the Session.fireSaveOrUpdate, which by default calls DefaultSaveOrUpdateEventListener. DefaultSaveOrUpdateEventListener does all the heavy lifting of checking to see if the object legal to save prior to actually saving the object.

These default listeners also invoke interceptors as briefly described in section 12.1 of the 3.2.0.cr4 manual.

This means that if someone starts adding event listeners of their own, they better make damn sure that they add in Hibernate’s as well. Otherwise Hibernate will very quietly do nothing!

I filed this bug in the hopes that the documentation would get changed:

Please add this (or equivalent) to the bottom of section 12.1. (Interceptors):

===========================================
Interceptors are invoked by Hibernate’s default event listeners. For example, interceptors’ onSave() method is invoked by Hibernate’s DefaultSaveOrUpdateEventListener
===========================================

Please add this (or equivalent) to the bottom of section 12.2 (Event System):

===========================================
When changing the event listeners be sure to keep the various Hibernate default listeners. These listeners actually perform much of Hibernate’s persistence work, including invocation of the interceptors. Without those default listeners, Hibernate will quietly do nothing.
===========================================

Event Default Hibernate EventListener Interceptor method called by default listener
PreLoadEvent DefaultPreLoadEventListener onLoad
PreInsertEvent
(return true to veto the insertion)
DefaultSaveOrUpdateEventListener
(on HSQL EntityIdentityInsertAction – which gets the generated id after the insertion)
?
SaveOrUpdateEvent DefaultSaveOrUpdateEventListener onSave
PostInsertEvent
(called even if the PreInsertEvent vetoed the insertion)
DefaultSaveOrUpdateEventListener ?
This entry was posted in amplafi, help notes, hibernate. Bookmark the permalink.

6 Responses to Hibernate’s event system

  1. Chris says:

    Any clue if hibernate uses any default EventListeners for post-commit-* events?

    I’m adding events for post-commit-update and post-commit-delete, and I want to make sure I don’t bork up anything.

    Good post though, as I totally agree with their poor documentation.

  2. patrick says:

    Thanks for the comment.

    Yeah, Hibernate does have a DefaultDeleteEventListener. While I haven’t verified it yet, I would not be surprised if that listener, if accidently, replaced hoses deletes.

    But even if no default listener exists today… it might tomorrow.

  3. Chris says:

    From what I can tell, there aren’t default listeners for the post-commit events…
    I’ve tested out my Event listener for the post-delete and post-update, and it all seems to work without hosing the system (Hibernate 3.1.2 of course).

    But you make a good point, who knows what comes in the future. That would kill us if we upgraded to Hibernate 3.whatever and it totally SNAFU’ed our system.

  4. Chris says:

    Also, it looks like there aren’t default listeners for post-update and post-delete events.

    I assumed that the DefaultSaveAndUpdateEventListener and DefaultDeleteEventListener would work, but I get an error when defining them onto my configuration.

    So, I *assume* that if there was a default for post-* they would include the name, like DefaultPostLoadEventListener.

    The documentation should really have a LISTING of all of the events and their related default listeners.

  5. Paulo says:

    OK, this seems like a good place to ask: is it possible to insert/remove specific event listeners in Hibernate at runtime?

  6. patrick says:

    Do you mean insert/remove before a Hibernate SessionFactory is created from a Configuration? Or while a SessionFactory is actively in use?

    Programmatically adding new EventListeners to a Configuration is straight-forward.

    However, adding/removing event listeners to a running SessionFactory is semi-sort-of-possible-but-not-recommended. Look at org.hibernate.impl.SessionFactoryImpl. Notice that most member variables are final – including the EventListeners and Interceptor variables.

    I would take this as a sign that Hibernate developers regard (rightly so) that such changes to the listener list as problematic. Especially since the actual core behavior of persistence is encapsulated in an EventListener! Suddenly for a period of time no data is being saved could be a possible race condition!

    Internally, we have an EventListener implementation that delegates to a list of EventListeners. This allows the dynamic add/remove – however, we are only doing this because of some configuration oddities.

    In normal practice I really would question if this is. Have you considered creating a new SessionFactory with the new EventListeners and Interceptors? Doing so is a more likely to be clean and avoid “interesting” race conditions.

    Also why are you trying to do this modification at runtime?

Leave a Reply

Your email address will not be published. Required fields are marked *