Hibernate @PostLoad никогда не вызывается - PullRequest
19 голосов
/ 10 мая 2010

Посмотрел на многих форумах, но не нашел ответа ... Простой материал, метод, аннотированный @PostLoad, никогда не вызывается ... добавлен слушатель через @EntityListeners, но проблема остается. Я использую конфигурацию на основе SessionFactory.

Ответы [ 5 ]

16 голосов
/ 10 мая 2010

Аннотация EJB3 @PostLoad не работает при использовании конфигурации на основе SessionFactory, метод после загрузки никогда не будет вызван.

Либо используйте перехватчики или события Hibernate , либо конфигурацию на основе EntityManager.

9 голосов
/ 22 мая 2012

Существует также альтернатива подходу перехватчиков или событий hibernate при использовании SessionFactory: реализация интерфейса Lifecycle .

4 голосов
/ 08 октября 2016

Вот как включить аннотации JPA после операции в Hibernate 5.

В Hibernate IntegratorServiceImpl используется API java.util.ServiceLoader, поэтому мы можем указать дополнительный список 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();
        }
    }
 }
2 голосов
/ 30 декабря 2013

Я также изо всех сил пытался заставить это работать на Hibernate4, используя фабрику сессий.

Я нашел решение довольно простым, но нигде не документированным с использованием Integrator (по-видимому, Hibernate4 работает с SessionFactory и слушателями). В проекте hibernate-entitymanager имеется Интегратор, который добавляет необходимых слушателей для связи аннотаций EJB3 @ PostLoad, ... с фабрикой сеансов. Просто объявите класс JpaIntegrator SPI .

Конкретно, просто добавьте файл с именем org.hibernate.integrator.spi.Integrator в папку META-INF / services и объявите в нем класс реализации ( org.hibernate.ejb.event.JpaIntegrator )

1 голос
/ 22 мая 2012

Или включите прослушиватели событий Hibernate, которые обрабатывают обратные вызовы JPA. Это именно то, что делает HEM. Как это делается, отличается в Hibernate 3 и Hibernate 4 (вы никогда не упоминали, какую версию вы используете); проверьте документацию для получения подробной информации о (a) участвующих слушателях событий и (b) как указать пользовательский набор слушателей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...