如何注册休眠的Spring实体监听器 [英] How to register hibernate spring entity listeners
问题描述
我已经建立了一个实体侦听器,但是还没有弄清楚如何注册它以便被调用.这一切都运行了,我在调试器中验证了 注册代码在启动时执行(显然成功).但是调试器永远不会在侦听器代码中停止.
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屋!