永远不会调用Hibernate @PostLoad

看了很多论坛,但没有找到答案……简单的东西,用@PostLoad注释的方法永远不会被调用…通过@EntityListeners添加了监听器,但问题仍然存在。 我正在使用基于SessionFactory的配置。

使用基于SessionFactory的配置时,EJB3 @PostLoad注释不起作用,永远不会调用后加载方法。

使用Hibernate的拦截器或事件或基于EntityManager的配置。

使用SessionFactory时,还有一种替代hibernate的拦截器或事件方法:实现Lifecycle接口。

以下是如何在Hibernate 5中启用JPA的post op注释。

Hibernate的IntegratorServiceImpl使用java.util.ServiceLoader API,因此我们可以指定我们希望SessionFactory使用的org.hibernate.integrator.spi.Integrator实现的附加列表。

我们需要做的就是在META-INF/services/org.hibernate.integrator.spi.Integrator指定一个服务提供者:

 # This allows us to use JPA-style annotation on entities, such as @PostLoad our.custom.JpaAnnotationsIntegrator 

您还需要确保适当版本的’ hibernate-entitymanager在您的类路径中。

our.custom.JpaAnnotationsIntegrator (取自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 org.hibernate.integrator.internal.IntegratorServiceImpl from * META-INF/services/org.hibernate.integrator.spi.Integrator file. * * Note: This code is lifted directly from org.hibernate.jpa.event.spi.JpaIntegrator * * @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(); } } } 

我也一直在努力使用会话工厂在Hibernate4上完成这项工作。

我发现解决方案非常简单,但没有使用Integrator记录(显然是Hibernate4处理SessionFactory和监听器的方式)。 hibernate-entitymanager项目提供了一个Integrator来添加所需的侦听器,以将EJB3的注释@PostLoad, …链接到会话工厂。 只需用SPI方式声明类JpaIntegrator

具体来说,只需在META-INF / services文件夹中添加一个名为org.hibernate.integrator.spi.Integrator的文件,并在其中声明实现类( org.hibernate.ejb.event.JpaIntegrator

或者启用处理JPA回调的Hibernate事件侦听器。 这正是HEM所做的。 如何做到这一点在Hibernate 3和Hibernate 4之间是不同的(你从未提到过你正在使用的版本); 检查文档以获取有关(a)所涉及的事件监听器和(b)如何指定自定义监听器集的详细信息。