2010-05-10 143 views
18

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

回答

15

当使用基于SessionFactory的配置时,EJB注释不起作用,后加载方法将永远不会被调用。

可以使用Hibernate的Interceptors or events或基于EntityManager的配置。

+2

回调便可使用SessionFactory的时候绝对工作。您只需自己启用正确的Hibernate事件侦听器。 – 2012-05-22 12:42:53

+0

以下是启用事件侦听器的方法:https://n1njahacks.wordpress.com/2016/10/07/jpa-callbacks-with-hibernates-sessionfactory-and-no-entitymanager/ – 2016-10-07 21:46:26

9

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

+3

但请注意以下错误:https: //hibernate.onjira。com/browse/HHH-6043,它也适用于Lifecycle.onLoad(在集合被初始化之前被调用 - 直到它在Hibernate 4.1.8中被修复) – Jakub 2012-10-12 14:43:11

1

或者启用处理JPA回调的Hibernate事件侦听器。这正是HEM所做的。 Hibernate 3和Hibernate 4之间的差异如何(您从未提及您使用的是哪个版本); (a)涉及的事件监听器和(b)如何指定自定义监听器组的详细信息。

+0

也许我很厚,但是我很难找到如何在Hibernate 4的文档中执行此操作。 – David 2015-01-12 15:00:15

2

我也一直在努力使这个工作在Hibernate4上,使用会话工厂。

我发现解决方案很简单,但没有记录在任何地方使用Integrator(显然是Hibernate4的方式来处理SessionFactory和侦听器)。 hibernate-entitymanager项目提供了一个集成器来添加所需的侦听器,以将EJB3的注释@PostLoad, ...链接到会话工厂。只需申报JpaIntegratorSPI的方式。

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

+0

不错的解决方案。仅供参考,从Hibernate 4.3.5开始,文件的内容应该是“org.hibernate.jpa.event.spi.JpaIntegrator”。 – 2015-11-23 15:02:29

+0

这也是我的解决方案,尽管我发现它会在Hibernate 5中打开冲洗级联。请参阅下面的答案以获得修复。 – 2016-10-07 23:12:25

+0

@Matt我知道它的一个很老的问题,但我应该在哪里找到这个META-INF/Services?我只能在我下载休眠文件的文件夹中找到它,并且在进行更改后,它仍然不起作用。 – 2017-03-17 21:48:58

3

这里是如何启用JPA的交运标注在Hibernate中5

Hibernate的IntegratorServiceImpl使用java.util.ServiceLoader API,所以我们可以指定org.hibernate.integrator.spi.Integrator实现额外的列表中,我们希望SessionFactory使用。

所有我们需要做的就是指定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“相应版本的罐子在classpath。

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 <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(); 
     } 
    } 
} 
相关问题