我已经构建了一个实体监听器,但还没有想出如何注册它以便它被调用。这一切都运行了,我在调试器中验证了 注册码在启动时执行(显然成功)。但调试器永远不会在侦听器代码中停止。
这是我的倾听者:
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;
请注意拦截器确实按预期工作(但遗憾的是我没有需要它的钩子。)
答案 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