如何注册hibernate spring实体监听器

时间:2018-01-23 02:35:16

标签: spring hibernate configuration entity listener

我已经构建了一个实体监听器,但还没有想出如何注册它以便它被调用。这一切都运行了,我在调试器中验证了 注册码在启动时执行(显然成功)。但调试器永远不会在侦听器代码中停止。

这是我的倾听者:

public class DirtyAwareListener implements PostLoadEventListener
{
   @Override
   public void onPostLoad(PostLoadEvent postLoadEvent)
   {
      if (postLoadEvent.getEntity() instanceof DirtyAware)
      {
         ((DirtyAware)postLoadEvent.getEntity()).commitFields();
      }
   }
}

这是注册组件:

@Component
public class HibernateListenerConfigurer
{
   @PersistenceUnit
   private EntityManagerFactory emf;

   @Autowired
   private SessionFactory sessionFactory;

   @PostConstruct
   protected void init()
   {
      DirtyAwareListener listener = new DirtyAwareListener();
//      SessionFactoryImpl sessionFactory = emf.unwrap(SessionFactoryImpl.class);
      EventListenerRegistry registry = ((SessionFactoryImpl)sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class);
      registry.getEventListenerGroup(EventType.POST_LOAD).appendListener(listener);
   }
}

以下是我的常规Hibernate配置代码如何生成会话工厂:

    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(getDataSource());
    sessionFactory.setPackagesToScan("com.my.entities");
    sessionFactory.setHibernateProperties(getHibernateProperties());
    sessionFactory.setEntityInterceptor(new DirtyAwareInterceptor());
    return sessionFactory;

请注意拦截器确实按预期工作(但遗憾的是我没有需要它的钩子。)

2 个答案:

答案 0 :(得分:1)

正如安东所建议的那样,我使用Integrator方法按需运行。他的回答中提供的链接并没有为我提供足够的信息让我发挥作用 - 我不得不参考多个帖子,并且还做了一些试验和错误。由于我找不到提供信息的单个帖子,所以我就是这样做的:

侦听器代码与上面相同。不需要配置代码 - 我删除了它。这是新的Integrator代码:

@Component
public class EventListenerIntegrator implements Integrator
{

   @Override
   public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactoryImplementor, SessionFactoryServiceRegistry sessionFactoryServiceRegistry)
   {
      EventListenerRegistry eventListenerRegistry =
            sessionFactoryServiceRegistry.getService(EventListenerRegistry.class);

      DirtyAwareListener t = new DirtyAwareListener();
      eventListenerRegistry.getEventListenerGroup(EventType.POST_LOAD).appendListener(t);
   }

   @Override
   public void disintegrate(SessionFactoryImplementor sessionFactoryImplementor, SessionFactoryServiceRegistry sessionFactoryServiceRegistry) {}
}

这是@Configuration类中修改过的getSessionFactory方法:

private static SessionFactory sessionFactory = null;

@Bean
public SessionFactory getSessionFactory()
{
    if (sessionFactory == null)
    {
        BootstrapServiceRegistry bootstrapRegistry =
              new BootstrapServiceRegistryBuilder()
                    .applyIntegrator(new EventListenerIntegrator())
                    .build();

        StandardServiceRegistryBuilder registryBuilder =
              new StandardServiceRegistryBuilder(bootstrapRegistry);

        registryBuilder.applySetting(org.hibernate.cfg.Environment.DATASOURCE, getDataSource());

        registryBuilder.applySettings(getHibernateProperties());

        StandardServiceRegistry registry = registryBuilder.build();

        MetadataSources sources = new MetadataSources(registry).addPackage("com.my.entities");
        sources.addAnnotatedClass(User.class);

        Metadata metadata = sources.getMetadataBuilder().build();

        sessionFactory = metadata.getSessionFactoryBuilder().build();

    }
    return sessionFactory;
}

注意:我认为不需要addPackage调用,也不执行任何操作。我原本希望它可以执行旧代码正在进行的包扫描,但它不会那样做。我只是将其改为明确添加每个带注释的类。

答案 1 :(得分:0)

要添加实体侦听器,请实现 org.hibernate.integrator.spi.Integrator 。请参见示例https://www.boraji.com/hibernate-5-event-listener-example

相关问题