Looked at many forums but haven't found answer...Simple stuff, method annotated with @PostLoad never gets invoked...added listener via @EntityListeners but problem remains. I'm using SessionFactory based configuration.
The EJB3 @PostLoad
annotation doesn’t work when using a SessionFactory
based configuration, the post-load method will never get called.
Either use Hibernate's Interceptors or events or an EntityManager
based configuration.
There is also an alternative to hibernate's interceptors or events approach when using SessionFactory: implementing Lifecycle interface.
Here's how to enable JPA's post op annotations in Hibernate 5.
Hibernate’s IntegratorServiceImpl
uses the java.util.ServiceLoader
API, so we can specify an additional list of org.hibernate.integrator.spi.Integrator
implementations we want the SessionFactory
to use.
All we need to do is specify a service provider in META-INF/services/org.hibernate.integrator.spi.Integrator
:
# This allows us to use JPA-style annotation on entities, such as @PostLoad
our.custom.JpaAnnotationsIntegrator
You will also need to ensure that ‘hibernate-entitymanager
‘ jar of the appropriate version is on your classpath.
our.custom.JpaAnnotationsIntegrator
(taken from org.hibernate.jpa.event.spi.JpaIntegrator
):
package our.custom;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.internal.MetadataImpl;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.jpa.event.internal.core.JpaPostDeleteEventListener;
import org.hibernate.jpa.event.internal.core.JpaPostInsertEventListener;
import org.hibernate.jpa.event.internal.core.JpaPostLoadEventListener;
import org.hibernate.jpa.event.internal.core.JpaPostUpdateEventListener;
import org.hibernate.jpa.event.internal.jpa.CallbackBuilderLegacyImpl;
import org.hibernate.jpa.event.internal.jpa.CallbackRegistryImpl;
import org.hibernate.jpa.event.spi.jpa.CallbackBuilder;
import org.hibernate.jpa.event.spi.jpa.ListenerFactory;
import org.hibernate.jpa.event.spi.jpa.ListenerFactoryBuilder;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
/**
* This integrator allows us to use JPA-style post op annotations on Hibernate entities.
*
* This integrator is loaded by <code>org.hibernate.integrator.internal.IntegratorServiceImpl</code> from
* <code>META-INF/services/org.hibernate.integrator.spi.Integrator</code> file.
*
* <b>Note</b>: This code is lifted directly from <code>org.hibernate.jpa.event.spi.JpaIntegrator</code>
*
* @author Val Blant
*/
public class JpaAnnotationsIntegrator implements Integrator {
private ListenerFactory jpaListenerFactory;
private CallbackBuilder callbackBuilder;
private CallbackRegistryImpl callbackRegistry;
@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
this.callbackRegistry = new CallbackRegistryImpl();
// post op listeners
eventListenerRegistry.prependListeners( EventType.POST_DELETE, new JpaPostDeleteEventListener(callbackRegistry) );
eventListenerRegistry.prependListeners( EventType.POST_INSERT, new JpaPostInsertEventListener(callbackRegistry) );
eventListenerRegistry.prependListeners( EventType.POST_LOAD, new JpaPostLoadEventListener(callbackRegistry) );
eventListenerRegistry.prependListeners( EventType.POST_UPDATE, new JpaPostUpdateEventListener(callbackRegistry) );
// handle JPA "entity listener classes"...
final ReflectionManager reflectionManager = ( (MetadataImpl) metadata )
.getMetadataBuildingOptions()
.getReflectionManager();
this.jpaListenerFactory = ListenerFactoryBuilder.buildListenerFactory( sessionFactory.getSessionFactoryOptions() );
this.callbackBuilder = new CallbackBuilderLegacyImpl( jpaListenerFactory, reflectionManager );
for ( PersistentClass persistentClass : metadata.getEntityBindings() ) {
if ( persistentClass.getClassName() == null ) {
// we can have non java class persisted by hibernate
continue;
}
callbackBuilder.buildCallbacksForEntity( persistentClass.getClassName(), callbackRegistry );
}
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
if ( callbackRegistry != null ) {
callbackRegistry.release();
}
if ( callbackBuilder != null ) {
callbackBuilder.release();
}
if ( jpaListenerFactory != null ) {
jpaListenerFactory.release();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With