This is an internal documentation. There is a good chance you’re looking for something else. See Disclaimer.
Listeners¶
This chapter explains the different kinds of listeners that exist, how and when they are called and how they can be registered.
EntityFacadeListener¶
An EntityFacadeListener is called
immediately after certain entity operations (e.g. EntityManager#create()
or Entity#setValue()
) and therefore
this listener is independent of any hibernate functionality.
Normally entity facade listeners are registered as spring beans which then are injected into the EntityFacadeListenerManagerImpl, which manages all listeners and can also be used to fire events.
It is also possible to temporarily register an EntityFacadeListener for the current context
using Context#addEntityFacadeListener()
. These listeners will be called for every entity and will only be called
for events of the context they belong to.
Likewise it is possible to add a temporary listener using EntityManager#addEntityFacadeListener()
which will only
be called for events of this entity manager.
When an event is fired, the EntityFacadeListenerManagerImpl searches for all registered listeners (that accept events of the affected entity) as well as all listeners of the current context and entity manager.
Note
EntityFacadeListener events
will not be called for session-only entities per default (override method handleSessionOnlyEntity
that session-only entities can also be handled by a listener).
entityCreating
event¶
This event is fired directly after a new entity instance is created (no fields are set at this point) by the EntityFactoryImpl. All entity instances are created by the entity factory (even those that are loaded from the database), but the event is only fired when a new instance is created by the user (not when an entity is loaded from the database). This is the case when no primary key is passed to the entity factory.
entityDeleting
event¶
This event is fired when Entity#delete()
is called.
Note that the entity won’t be deleted from the database until the transaction is committed.
entityChanging
event¶
This event is fired every time a field is updated (i.e. if Entity#setValue()
or the setter for this field is called).
This is done in AbstractHibernateEntity#internalSetValue()
which is called by both Entity#setValue()
and the
generated setter method.
entityRelationChanging
event¶
This event is fired every time a relation is modified (i.e. if an entity is added to or removed from a relation).
This is done in AbstractRelationAdapter#fireRelationChangingEvent()
which in turn is called by the
ToOneRelationAdapter and the
ToManyRelationAdapter.
An event is also always fired for the reverse side of the relation.
See the chapter Abstract entity base class for a description when the adjusting
flag is set to true.
entityReceivedValues
event (deprecated)¶
This event is fired when a newly created entity receives its primary key after it was inserted into the database.
See EntityTransactionContextImpl#executeEntityOperations
.
This event is rarely used and mostly implemented for compatibility reasons. New listeners should not use this event
anymore.
EntityListener¶
An EntityListener is used to listen to ‘after-commit’ events. This means that these listeners are only called after a transaction has been successfully committed.
For this purpose we use hibernate’s PostCommitInsertEventListener, PostCommitUpdateEventListener and PostCommitDeleteEventListener.
These listener interfaces are implemented by AfterCommitListenerImpl,
which delegates the hibernate events to the corresponding EntityListener.
This class is bound to the hibernate events POST_COMMIT_INSERT
, POST_COMMIT_UPDATE
and POST_COMMIT_DELETE
(see HibernateCoreBootstrapContribution).
Listeners can either be contributed as spring beans or registered temporarily through the Context
or EntityManager
(same as the entity facade listener).
Hibernate does not fire a POST_COMMIT_UPDATE
for an entity if the only change is in a collection and this collection is not the owning side of the association.
For this special use case there is the CustomFlushEntityEventListener.
This is class is bound to the hibernate events FLUSH_ENTITY
and checks every entity in the persistence context whether
this event needs to be fired manually.
If no event would be fired by hibernate but the entity has a change in (the non-owning side of) a collection, the listener
registers a AfterTransactionCompletionProcess
(the event should only be fired if the transaction was completed successfully),
which fires the missing event manually, with the ActionQueue.
CommitListener¶
A CommitListener listens to events that are fired just before or after a transaction is committed. The commit listeners are managed by the EntityFacadeListenerManagerImpl.
Commit listeners can be registered for the current context by calling Context#addCommitListener()
, which in turn
registers the listener with the EntityFacadeListenerManagerImpl.
As the EntityFacadeListenerManagerImpl tracks all commit listeners by session in a map, it is important that they will be removed properly. To avoid memory leaks when the user forgets to remove a commit listener, a SessionEventListener, which removes all commit listeners when the session ends, is registered once per session.
The events are fired by the TransactionControlImpl (see Transaction Lifecycle)
just before or after the database transaction is committed. CommitListener#onAfterCommit()
is only called if the commit
was successful.
The method afterFlush()
is called after the hibernate session is flushed, but before the transaction is committed.
This means that all data that has been modified during this transaction is already available on the database when these listeners
are called. The method returns a boolean
which indicates if the current listener has changed data on the database.
If true
is returned, the session is flushed again before the afterFlush()
method of the next listener is called.
This functionality is usually used through the CollectingAfterFlushEntityListener.
Since this is the last listener that will be called before a transaction is committed, they must be ordered carefully using the priority()
method, to make sure that no entity events are missed, because they were triggered by a listener that is executed later.
TransactionListener¶
A TransactionListener is another listener that gets notified by transaction events. But in contrast to the CommitListener it is meant to be used internally by the persistence framework only. This is a replacement of the TransactionAware of the old persistence implementation.
TransactionListener#onTransactionStart()
is called when a new transaction has been started
TransactionListener#onCommit()
is called afterCommitListener#onBeforeCommit()
has already been called and can be used to clean up resources for example.
TransactionListener#onRollback()
is called just before a transaction will be rolled back
TransactionListener#afterTransaction()
is called after every transaction (whether successful or not), but beforeCommitListener#onAfterCommit()
A TransactionListener can be registered with the TransactionControl of a transaction.
In addition it can also be added through the PersistenceService
(addTransactionListener()
method). Listeners registered in this way will be applied to all transactions of the current
session and are passed to the TransactionControl when
a new transaction is started.
ContextListener¶
The ContextListener is part of the legacy API and contains two methods:
transactionStarted()
is called when a new transaction has been started
contextDestroying()
is called when a context is being closed
It can be registered using the Context#addContextListener()
method and will be wrapped in a
ContextListenerAdapter.
The adapter class implements both TransactionListener
(to implement the transactionStarted()
method)
and SessionFactoryManagerListener
(to implement the contextDestroying()
method) to make sure that events are properly fired through both the old and new API.
If the context is already closed, added listeners will be silently ignored to avoid memory leaks.
ContextCreationListener¶
The ContextCreationListener is also implemented using an adapter class
to delegate the events to the SessionFactoryManagerListener#sessionCreated()
event.