永远不会调用Hibernate @PostLoad

时间:2010-05-10 12:47:47

标签: java hibernate orm

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

5 个答案:

答案 0 :(得分:16)

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

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

答案 1 :(得分:9)

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

答案 2 :(得分:4)

以下是如何在Hibernate 5中启用JPA的后期操作注释。

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”jar在您的类路径中。

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();
        }
    }
 }

答案 3 :(得分:2)

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

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

具体而言,只需在 META-INF / services 文件夹中添加名为 org.hibernate.integrator.spi.Integrator 的文件,并在其中声明实现类(< EM> org.hibernate.ejb.event.JpaIntegrator )

答案 4 :(得分:1)

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