代码之家  ›  专栏  ›  技术社区  ›  tropikalista

永远不会调用hibernate@postload

  •  19
  • tropikalista  · 技术社区  · 16 年前

    查看了许多论坛,但没有找到答案……简单的东西,用@postload注释的方法永远不会被调用……通过@entitylisteners添加了listener,但问题仍然存在。我正在使用基于会话工厂的配置。

    5 回复  |  直到 9 年前
        1
  •  16
  •   Pascal Thivent    16 年前

    EJB3 @PostLoad 当使用 SessionFactory 基于配置,永远不会调用后加载方法。

    要么使用Hibernate's Interceptors or events EntityManager 基于配置。

        2
  •  9
  •   Vadzim    14 年前

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

        3
  •  4
  •   Val Blant    9 年前

    下面介绍如何在Hibernate5中启用JPA的操作后注释。

    休眠 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();
            }
        }
     }
    
        4
  •  2
  •   Matt    12 年前

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

    我发现这个解决方案非常简单,但是没有使用集成器记录到任何地方(显然是Hibernate4处理会话工厂和侦听器的方法)。 这个 休眠实体管理器 Project提供了一个集成器来添加链接EJB3注释所需的侦听器。 @ PostLoad, …到会话工厂。只需声明类 JPB 这个 SPI 方式。

    具体来说,只需添加一个名为 org.hibernate.integrator.spi.integrator集成器 META-INF/服务 文件夹并声明其中的实现类( org.hibernate.ejb.event.jpaintegrator )

        5
  •  1
  •   Steve Ebersole    14 年前

    或者启用处理JPA回调的休眠事件侦听器。这正是hem所做的。在Hibernate3和Hibernate4之间,这两种方式是不同的(您从未提到过您使用的是哪个版本);有关(a)所涉及的事件侦听器和(b)如何指定自定义侦听器集的详细信息,请查阅文档。