Grails 4多数据源查询报错:No Session found for current thread
多数据源下Hibernate Session缺失问题解决
问题场景
在Grails项目中配置了多数据源,实体类Test通过mapping指定使用数据源two,且对应的表已成功在目标数据库创建。但调用Test.list([:])或Test.two.list([:])时,抛出如下错误:
Caused by: org.hibernate.HibernateException: No Session found for current thread
项目配置(application.yml)
--- hibernate: cache: queries: false use_second_level_cache: false use_query_cache: false dataSource: pooled: true jmxExport: true driverClassName: com.mysql.cj.jdbc.Driver dialect: org.hibernate.dialect.MySQL5InnoDBDialect username: root password: "" environments: development: pathFiles: C://pw-inventory dataSource: dbCreate: update url: jdbc:mysql://localhost:3306/inventory_dev dataSources: two: dbCreate: update url: jdbc:mysql://localhost:3306/pw-security
实体类代码
class Test { String a String b static mapping = { datasource('two') } }
解决方案
在事务上下文执行查询:Grails会在控制器、服务层自动绑定Hibernate会话,但如果是在Bootstrap、自定义脚本或非托管代码中执行查询,需要手动通过事务包裹:
// 针对实体指定的数据源 Test.withTransaction { Test.list() } // 显式指定数据源(可选) Test.withTransaction('two') { Test.list() }完善多数据源的Hibernate配置:确保
dataSources.two的Hibernate配置完整,避免会话工厂初始化异常。可在application.yml中补充:environments: development: dataSources: two: dbCreate: update url: jdbc:mysql://localhost:3306/pw-security hibernate: cache: use_second_level_cache: false手动管理会话(非托管线程场景):如果是在自定义线程或异步任务中执行查询,需要手动获取并绑定会话到当前线程:
def sessionFactory = grailsApplication.mainContext.getBean('sessionFactory_two') def session = sessionFactory.openSession() try { org.hibernate.context.internal.ThreadLocalSessionContext.bind(session) def result = Test.list() // 处理查询结果 } finally { session.close() org.hibernate.context.internal.ThreadLocalSessionContext.unbind(sessionFactory) }核对Grails版本适配性:不同Grails版本的多数据源会话管理逻辑有差异,比如Grails 2.x与3.x的配置方式不同,确保代码和配置与当前使用的Grails版本匹配。
内容的提问来源于stack exchange,提问作者FrEqDe
相关产品推荐
相关产品推荐

