永远不会调用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 fromorg.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)如何指定自定义监听器集的详细信息。
- Hibernate一到零或一个映射
- @OneToMany映射JPA中的父ID为null
- Spring Data JPA JpaRepository.save(实体)不返回数据库默认值
- 创建一个可以处理所有类型的CRUD操作的类。 每次我需要做CRUD时都不需要创建SessionFactory或Session对象
- @Transactional的奇怪行为(propagation = Propagation.REQUIRES_NEW)
- 如何使用hibernate生成Custom Id,同时它必须是表的主键
- Hibernate条件查询不同对象的不同属性
- Hibernate无法实例化默认的tuplizer – 无法找到getter
- 如何使用hibernate调用存储过程?