From: "Gail Badner" <gbadner(a)redhat.com>
To: "Steve Ebersole" <steve(a)hibernate.org>, "Emmanuel Bernard"
<emmanuel(a)hibernate.org>
Sent: Friday, June 20, 2014 4:25:56 PM
Subject: Overriding JpaMergeEventListener with JpaEntityCopyAllowedMergeEventListener
I am trying into figure out how to override JpaMergeEventListener with
JpaEntityCopyAllowedMergeEventListener as described in [1]. This
documentation does not describe how to deal with injecting CallbackRegistry
into an overridden MergeEventListener.
CallbackRegistry is an SPI, but JpaMergeEventListener and
CallbackRegistryConsumer are internal.
JpaEntityCopyAllowedMergeEventListener is also internal.
I was planning to document MyIntegrator.integrate(..) for enabling entity
copies, but I don't like the idea of documenting an internal event listener
for that functionality.
Here is one alternative that minimizes exposing private classes/methods:
public class MyIntegrator implements org.hibernate.integrator.spi.Integrator
{
public void integrate(
Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
final EventListenerRegistry eventListenerRegistry =
serviceRegistry.getService( EventListenerRegistry.class );
final MergeEventListener mergeEventListener =
mergeEventListenerGroup.listeners().iterator().next();
final JpaEntityCopyAllowedMergeEventListener
entityCopyAllowedMergeEventListener =
new JpaEntityCopyAllowedMergeEventListener();
entityCopyAllowedMergeEventListener.initializeFrom(
mergeEventListener );
registry.setListeners( EventType.MERGE,
entityCopyAllowedMergeEventListener );
}
...
}
public class JpaEntityCopyAllowedMergeEventListener extends
JpaMergeEventListener {
...
public void initializeFrom(MergeEventListener mergeEventListener) {
if ( JpaMergeEventListener.class.isInstance( mergeEventListener ) ) {
injectCallbackRegistryFrom( (JpaMergeEventListener)
mergeEventListener );
}
}
...
}
public class JpaMergeEventListener extends DefaultMergeEventListener
implements CallbackRegistryConsumer {
...
protected void injectCallbackRegistryFrom(JpaMergeEventListener
jpaMergeEventListener) {
injectCallbackRegistry( jpaMergeEventListener.callbackRegistry );
}
...
}
Another alternative is to change JpaEntityCopyAllowedMergeEventListener to be
a Proxy that holds an instance of the original JpaMergeEventListener.
Everything except for createEntityCopyObserver() could be delegated to the
stored JpaMergeEventListener. There would be no need to call
injectCallbackRegistry(CallBackRegistry).
It might be possible to have one Proxy for
JpaEntityCopyAllowedMergeEventListener and
EntityCopyAllowedMergeEventListener holding an instance of
MergeEventListener, but that Proxy wouldn't implement
CallbackRegistryConsumer or HibernateEntityManagerEventListener. Does that
matter for an overridden event listener if the CallbackRegistry does not
have to be injected?
Is there some other way of doing this that I've missed?
Thanks,
Gail
[1]
http://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/ch07.html#reg...