添加@Audited注解后HQL查询无结果,EntityManager.find正常的问题求助
Hibernate Envers标注@Audited后JPQL查询无结果问题排查
问题场景
为实体A添加@Audited注解后,通过命名查询queryA按businessKey查询返回空列表;移除@Audited后查询恢复正常。entityManager.find()按ID可正常获取实体,日志输出的SQL语句直接在数据库执行能得到预期结果,使用的Hibernate版本为6.2.46。
实体及查询代码:
@NamedQuery(name = "queryA", query = "SELECT u FROM A u " + "WHERE u.businessKey=:key") @Entity @Audited @Table(name = "A") public class A { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ID", unique = true, nullable = false) private long id; @Column(name = "BUSINESS_KEY", nullable = false) private long businessKey; // 其他字段及方法 }
日志输出的SQL:
select u1_0.ID, u1_0.BUSINESS_KEY from A u1_0 where u1_0.BUSINESS_KEY=?;
可能原因及解决方案
1. Hibernate 6.2.x Envers版本bug
6.2.46版本的Envers存在针对IDENTITY主键实体的JPQL查询过滤bug,审计拦截器错误地拦截了非ID字段的查询结果。
- 解决方式:升级Hibernate到6.2.5.Final或更高版本(该bug在后续版本中已修复);或为实体显式添加
@Audited(withModifiedFlag = true)注解调整审计策略。
2. 参数绑定类型不匹配
Envers可能改变了参数绑定的处理逻辑,即便SQL语句正确,参数类型不匹配也会导致无结果返回。
- 验证:确保传入的
:key参数类型与businessKey完全一致(均为long基本类型或Long包装类型),避免隐式类型转换; - 解决方式:显式转换参数类型后再传入查询。
3. 审计记录不完整
Envers默认要求实体的所有操作都生成审计记录,若A_AUD表中缺少对应实体的插入记录(REVTYPE=0),Hibernate可能判定该实体未被审计,从而过滤结果。
- 验证:检查
A_AUD表是否存在与A表对应的完整记录; - 解决方式:确保实体插入时事务正常提交,触发Envers的审计逻辑;或手动补全
A_AUD表的审计记录。
4. 会话缓存干扰
Envers可能改变了Hibernate会话缓存的行为,旧缓存数据导致查询结果异常。
- 解决方式:查询前执行
entityManager.flush()和entityManager.clear(),清除会话缓存后再执行查询。
验证步骤
- 开启
org.hibernate.SQL和org.hibernate.type日志级别,查看参数绑定值和结果提取过程,确认数据流转是否正常; - 使用原生SQL查询(
entityManager.createNativeQuery(sql, A.class)),判断问题出在JPQL解析还是结果映射环节; - 检查
A_AUD表的审计记录完整性,确认REVTYPE和关联字段正确。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

