JPA原生查询与Oracle直接查询结果不一致问题排查
以下是几种可能导致结果不一致的原因:
Hibernate会话过滤器影响:如果你的EntityManager启用了全局过滤器(比如通过
@Filter注解配置的过滤规则),执行原生查询时Hibernate会自动应用这些过滤器,过滤掉部分符合条件的记录。而直接在数据库执行SQL时不会受过滤器影响,所以返回结果条数不同。参数类型不匹配导致隐式转换差异:Kotlin中的
lId是Int类型,若数据库中id字段是Number类型,Hibernate绑定参数时的类型转换逻辑可能和Oracle直接执行SQL时的隐式转换不一致。比如极端情况下,若id字段实际存储的是字符串类型,参数绑定成数值型会导致匹配范围缩小,只返回一条记录。关联查询条件写错:你提供的关联查询SQL中,
WHERE p1.id=:anId的条件只会返回p1中id等于参数的那条记录,本身就只能得到1条结果。如果你的预期是获取所有和id=103的Person同名的记录,应该把条件改成WHERE p2.id=:anId,否则关联查询的写法本身就有逻辑错误。数据库会话环境差异:Hibernate使用的数据库会话和你直接执行SQL的会话可能有不同的参数配置,比如NLS字符集、大小写敏感设置(
NLS_COMP/NLS_SORT)。如果name字段的匹配规则在两个会话中不同,会导致外层查询匹配的记录数不一样。Hibernate缓存干扰:虽然原生查询默认绕过一级缓存,但如果之前查询过id=103的Person实体并缓存,Hibernate可能在处理结果时误从缓存中取数据,而不是完全依赖数据库返回的结果集。不过这种情况概率较低,通常原生查询会直接走数据库。
内容的提问来源于stack exchange,提问作者Pipo

