如何注册休眠的Spring实体监听器 [英] How to register hibernate spring entity listeners

查看:101
本文介绍了如何注册休眠的Spring实体监听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have built an entity listener but have not figured out how to register it so that it will get called. This all runs, and I verified in the debugger that the registration code executes (apparently successfully) at startup. But the debugger never stops in the listener code.

这是我的听众:

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配置代码如何生成会话工厂:

Here is how my general Hibernate configuration code generates a session factory:

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

请注意,拦截器确实按预期工作(但不幸的是,在我需要它们的地方没有钩子).

Note that the interceptor does work as expected (but unfortunately does not have hooks where I need them.)

推荐答案

我使用Anton建议的Integrator方法按需完成了这项工作.他的回答中提供的链接没有为我提供足够的信息来使它起作用-我不得不引用多个帖子,并且还要进行一些反复试验.由于我找不到提供该信息的帖子,因此,我是这样做的:

I got this working as desired using the Integrator approach as Anton suggested. The link provided in his answer did not provide sufficient information for me to get this to work - I had to reference multiple posts and also do a bit of trial and error. Since I could not find a single post which provided the info, here is how I did it:

侦听器代码与上面的相同.不需要配置程序代码-我删除了它.这是新的集成商代码:

The listener code is the same as the above. The Configurer code is not needed - I deleted it. Here is the new Integrator code:

@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方法:

And here is the revised getSessionFactory method on my @Configuration class:

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调用,并且不执行任何操作.我曾希望它能够对旧代码所做的包进行扫描,但不会这样做.我只是将其更改为显式添加每个带注释的类.

Note: I think the addPackage call is not needed and does not do anything. I had hoped it would do the package scan the old code was doing, but it does not do that. I simply changed that to explicity add each annotated class.

这篇关于如何注册休眠的Spring实体监听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆