java 休眠@PostLoad 永远不会被调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2802676/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate @PostLoad never gets invoked
提问by tropikalista
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.
看了很多论坛,但没有找到答案……简单的东西,用@PostLoad 注释的方法永远不会被调用……通过@EntityListeners 添加了监听器,但问题仍然存在。我正在使用基于 SessionFactory 的配置。
采纳答案by Pascal Thivent
The EJB3 @PostLoadannotation doesn't work when using a SessionFactorybased configuration, the post-load method will never get called.
EJB3@PostLoad注释在使用SessionFactory基于配置时不起作用,post-load 方法永远不会被调用。
Either use Hibernate's Interceptors or eventsor an EntityManagerbased configuration.
无论是使用Hibernate的拦截器或事件或一个EntityManager基础的配置。
回答by Vadzim
回答by Val Blant
Here's how to enable JPA's post op annotations in Hibernate 5.
以下是在 Hibernate 5 中启用 JPA 的 post op 注释的方法。
Hibernate's IntegratorServiceImpluses the java.util.ServiceLoaderAPI, so we can specify an additional list of org.hibernate.integrator.spi.Integratorimplementations we want the SessionFactoryto use.
HibernateIntegratorServiceImpl使用java.util.ServiceLoaderAPI,因此我们可以指定org.hibernate.integrator.spi.Integrator我们想要SessionFactory使用的附加实现列表。
All we need to do is specify a service provider in META-INF/services/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
You will also need to ensure that ‘hibernate-entitymanager‘ jar of the appropriate version is on your classpath.
您还需要确保hibernate-entitymanager相应版本的“ ”jar 在您的类路径中。
our.custom.JpaAnnotationsIntegrator(taken from org.hibernate.jpa.event.spi.JpaIntegrator):
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();
}
}
}
回答by Matt
I've also been struggling to make this work on Hibernate4, using the session factory.
我也一直在努力使用会话工厂在 Hibernate4 上完成这项工作。
I found the solution quite simple but not documented anywhere using Integrator (Apparently the Hibernate4's way to deal with SessionFactory and listeners). The hibernate-entitymanagerproject provides an Integrator to add the required listeners to link EJB3's annotations @PostLoad,... to the session factory. Just declare the class JpaIntegratorthe SPIway.
我发现该解决方案非常简单,但没有在任何使用 Integrator 的地方记录(显然是 Hibernate4 处理 SessionFactory 和侦听器的方式)。在休眠-EntityManager的项目提供了一个集成所要求的侦听器添加到链接EJB3的注解@PostLoad,...到会话工厂。只需以SPI方式声明JpaIntegrator类即可。
Concretely, just add a file named org.hibernate.integrator.spi.Integratorin the META-INF/servicesfolder and declare the implementation class in it (org.hibernate.ejb.event.JpaIntegrator)
具体来说,只需在META-INF/services文件夹中添加一个名为org.hibernate.integrator.spi.Integrator的文件,并在其中声明实现类(org.hibernate.ejb.event.JpaIntegrator)
回答by Steve Ebersole
Or enable the Hibernate event listeners that handle JPA callbacks. That is exactly what HEM does. How that is done is different between Hibernate 3 and Hibernate 4 (you never mentioned which version you are using); check the documentation for details on (a) the event listeners involved and (b) how to specify custom set of listeners.
或者启用处理 JPA 回调的 Hibernate 事件侦听器。这正是 HEM 所做的。Hibernate 3 和 Hibernate 4 的实现方式不同(您从未提到您使用的是哪个版本);有关 (a) 所涉及的事件侦听器和 (b) 如何指定自定义侦听器集的详细信息,请查看文档。

