每次Jpa调用都会休眠Hibernate PostUpdateEventListener

时间:2019-04-09 08:52:48

标签: spring hibernate

我将Spring Data JPA与hibernate 5.3.7内核一起使用。我编写了一个实现PostUpdateEventListener的自定义侦听器。我的要求是在每次数据库更新时都调用一个回调方法,即仅用于实体的更新操作调用。

但是onPostUpdate中的PostUpdateEventListener会在每次Jpa调用时调用,即与数据库操作无关。这对我来说是奇怪的行为。还是听者的行为相同?

我正在使用Hibernate 5.3.7,除了以下link

之外,我看不到太多详细的文档。

还要附加用于注册我的自定义侦听器和所需配置的类。

  1. CustomEventListener类:

    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    
    import org.hibernate.event.spi.PostUpdateEvent;
    import org.hibernate.event.spi.PostUpdateEventListener;
    import org.hibernate.persister.entity.EntityPersister;
    import org.springframework.stereotype.Component;
    
    @Component
    public class CustomEventListener implements PostUpdateEventListener {
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        public static final CustomEventListener INSTANCE = new CustomEventListener();
        @PersistenceContext
        private EntityManager entityManager;
        /* (non-Javadoc)
         * @see org.hibernate.event.spi.PostCollectionUpdateEventListener#onPostUpdateCollection(org.hibernate.event.spi.PostCollectionUpdateEvent)
         */
    
        @Override
        public boolean requiresPostCommitHanding(EntityPersister persister) {
            // TODO Auto-generated method stub
    
            return false;
        }
    
        /* (non-Javadoc)
         * @see org.hibernate.event.spi.PostUpdateEventListener#onPostUpdate(org.hibernate.event.spi.PostUpdateEvent)
         */
        @Override
        public void onPostUpdate(PostUpdateEvent event) {
            // TODO Auto-generated method stub
            System.out.println("hello");
        }
    
    }`
    
  2. HibernateConfig类:用于在现有配置中配置hibernate.integrator_provider属性

    import java.util.Collections;
    import java.util.Map;
    
    import org.hibernate.jpa.boot.spi.IntegratorProvider;
    import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
    import org.springframework.stereotype.Component;
    
    /**
     * @author satyam.kaushik
     * @version  Last modified 09-Apr-2019
     */
    
    @Component
    public class HibernateConfig implements HibernatePropertiesCustomizer {
    
        @Override
        public void customize(Map<String, Object> hibernateProperties) {
            hibernateProperties.put("hibernate.integrator_provider",
                    (IntegratorProvider) () -> Collections.singletonList(MetadataExtractorIntegrator.INSTANCE));
        }
    }
    
  3. MetadataExtractorIntegrator类注册侦听器     `

    import org.hibernate.boot.Metadata;
    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.service.spi.SessionFactoryServiceRegistry;
    
    public class MetadataExtractorIntegrator implements Integrator {
    
        public static final MetadataExtractorIntegrator INSTANCE = new MetadataExtractorIntegrator();
    
        @Override
        public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory,
                SessionFactoryServiceRegistry serviceRegistry) {
    
            final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);
    
            eventListenerRegistry.appendListeners(EventType.POST_UPDATE, CustomEventListener.INSTANCE);
    
        }
    
        @Override
        public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
    
        }
    }`
    

    我还尝试了API提供的其他内置侦听器,即SaveOrUpdateEventListenerMergeEventListener,但没有任何帮助。看来侦听器正在为每个JPA调用而不是仅更新调用。

还要为引发问题的Get请求附加以下日志(即,调用不应调用的侦听器方法)

0:0:0:0:0:0:0:1--[09 / Apr / 2019:16:38:38 +0530]“选项/ rippsadm / rest / device?sort-column =&sort- order = asc&page-no = 1&page-size = 15 HTTP / 1.1“ 200-

0:0:0:0:0:0:0:1--[09 / Apr / 2019:16:38:38 +0530]“ OPTIONS / rippsadm / rest / device / filter HTTP / 1.1” 200 -

0:0:0:0:0:0:0:1--[09 / Apr / 2019:16:38:41 +0530]“ GET / rippsadm / rest / device / filter HTTP / 1.1” 200 1918

0:0:0:0:0:0:0:1--[09 / Apr / 2019:16:38:41 +0530]“ GET / rippsadm / rest / device?sort-column =&sort- order = asc&page-no = 1&page-size = 15 HTTP / 1.1“ 200 6422

1 个答案:

答案 0 :(得分:0)

Solution : Customize the Handling of EventType.POST_UPDATE Events for the entities which doesn't need to post process but triggering update call to Jpa for each request.

Identify if any insert statement executed during the Get call by using show_sql=true. If yes then there can be multiple reasons including auditing, some setter method update the entity in services, Or some interceptor invoke an insert/update call etc.


In my case hibernate enver auditing was root cause.Setting show_sql=true was showing the hibernate insert query for one of audit managed entity and REVINFO hibernate enver default table.

 In my case this entity never need to post process.

Therefore I've added an if condition inside onPostUpdate method of Custom listener  to skip post processing for the entity resolved the issue.

@Override
    public void onPostUpdate(PostUpdateEvent event) {
if(!(event.getEntity().getClass().getTypeName().contains("<EntityName>"))) {
           //do your post processing logic
        }
  }