Hibernate 6调用JPA方法频繁报InvalidDataAccessApiUsageException问题
首先将异常信息翻译成中文:
org.springframework.dao.InvalidDataAccessApiUsageException: 非法的pop()操作,JdbcValuesSourceProcessingState不匹配
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:368)
这个异常本质是Hibernate处理JDBC结果集时的内部状态栈出现不匹配,以下是常见排查和修复方案:
确保EntityManager的线程安全
禁止在多线程环境下共享同一个EntityManager实例,也不要手动持有EntityManager引用跨事务使用。Spring中通过@PersistenceContext注入的EntityManager是事务范围的代理,本身是安全的;但如果自行创建EntityManager并复用,会触发状态冲突。所有JPA操作都要放在@Transactional注解的方法内,由Spring管理事务和EntityManager生命周期。升级Hibernate到稳定版本
Hibernate 6的早期版本(如6.0.x、6.1.x部分子版本)存在结果集处理状态管理的bug,官方在6.2.x及以后版本中已修复该问题。直接升级到最新的6.2.x或6.3.x稳定版,大概率能解决异常。规范自定义SQL查询写法
如果使用原生SQL查询或自定义结果集处理器(如ResultSetExtractor、RowMapper),不要直接操作Hibernate底层的JdbcValuesSourceProcessingState对象。尽量使用JPA标准的createNativeQuery配合@SqlResultSetMapping映射结果,避免手动遍历结果集时干扰Hibernate内部状态。校验Spring与Hibernate版本兼容性
Spring ORM和Hibernate 6版本必须匹配:只有Spring 6.x系列能完美兼容Hibernate 6.x,若仍用Spring 5.x搭配Hibernate 6,会出现上下文管理冲突。升级Spring到6.x版本,保持依赖版本一致。
内容的提问来源于stack exchange,提问作者Jana

