非Spring遗留应用从Hibernate3迁移至5.6如何注册Event Listeners
Hibernate 5.6 事件监听器注册适配方案
方案一:SPI自动注册(无需修改现有SessionFactory构建代码,优先推荐)
该方案对遗留代码侵入性最低,完全不用调整你现有的buildSessionFactory逻辑:
- 在项目的classpath根目录(比如
src/main/resources)下创建层级目录META-INF/services - 在该目录下新建名为
org.hibernate.integrator.spi.Integrator的文本文件 - 文件内容仅填写你自定义Integrator的全限定类名,示例如下:
com.app.server.services.db.eventlisteners.MyEventListenerIntegrator
Hibernate启动时会自动扫描SPI配置加载该Integrator,完成监听器注册。
方案二:手动修改SessionFactory构建逻辑
如果你不想用SPI自动注册,可以调整现有buildSessionFactory代码,手动把Integrator注入到服务注册表中,修改后的代码如下:
protected static SessionFactory buildSessionFactory(Database db) { if (db == null) { throw new NullPointerException("Database specifier cannot be null"); } StandardServiceRegistry serviceRegistry = null; try { Configuration config = createSessionFactoryConfiguration(db); String url = config.getProperty("connection.url"); String user = config.getProperty("connection.username"); String password = config.getProperty("connection.password"); try { String dbDriver = config.getProperty("hibernate.connection.driver_class"); Class.forName(dbDriver); Connection conn = DriverManager.getConnection(url, user, password); } catch (SQLException error) { logger.info("Didn't find driver, on QA or production, so it's okay to assume we have DB connection"); error.printStackTrace(); } // 手动注册自定义Integrator BootstrapServiceRegistry bootstrapRegistry = new BootstrapServiceRegistryBuilder() .applyIntegrator(new MyEventListenerIntegrator()) .build(); // 构建StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder(bootstrapRegistry) .applySettings(config.getProperties()) .build(); // 用带自定义服务注册表的方式构建SessionFactory SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); sessionFactoryConfigs.put(sessionFactory, config); return sessionFactory; } catch (Throwable ex) { logger.error("Initial SessionFactory creation failed.", ex); // 异常场景销毁服务注册表避免内存泄漏 if (serviceRegistry != null) { StandardServiceRegistryBuilder.destroy(serviceRegistry); } throw new ExceptionInInitializerError(ex); } }
注意事项
- 检查你当前写的Integrator代码逻辑:Hibernate3原有逻辑中
pre-load事件绑定的是EkoSecurityHibernateEventListener,现有Integrator里4个事件都用了MySecurityHibernateEventListener,需要修正对应逻辑避免业务错误 - 确保导入的
EventType类包路径为org.hibernate.event.spi.EventType,不要导错其他版本的同名类 - 如果你的自定义监听器是无状态的,建议复用同一个实例,不要每个事件都new新的对象
内容的提问来源于stack exchange,提问作者tjholmes66
相关产品推荐
相关产品推荐

