【发布时间】:2018-10-26 05:14:10
【问题描述】:
我通过 hibernate-envers 库配置了审计,它工作正常,直到我想通过 AuditReader API 读取历史记录。
这是代码:
AuditReader auditReader = AuditReaderFactory.get(entityManager);
List<Number> revisionNumbers = auditReader.getRevisions(Queue.class, queue.getId());
for (Number rev : revisionNumbers) {
Queue auditedQueue = auditReader.find(Queue.class, queue.getId(), rev);
audQueues.add(auditedQueue);
}
抛出的异常是org.postgresql.util.PSQLException: ERROR: operator does not exist: smallint bytea 提示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。 位置:879
我配置了 sql 日志记录,但我看到了失败的查询:
select queue_aud0_.ID as ID12_, queue_aud0_.REV as REV12_, queue_aud0_.REVTYPE as REVTYPE12_ from CMSMS_QUEUE_AUD queue_aud0_ where (queue_aud0_.REV=(select max(queue_aud1_.REV) from CMSMS_QUEUE_AUD queue_aud1_ where (queue_aud1_.REV<=? )and(queue_aud0_.ID=queue_aud1_.ID )))and(queue_aud0_.REVTYPE<>? )and(queue_aud0_.ID=? )
选择的列比较多,但是现在不重要了……hibernate使用的参数有:
bindNamedParameters() TEST_NEW -> _p1 [3]
bindNamedParameters() DEL -> _p0 [2]
bindNamedParameters() 5 -> revision [1]
我尝试使用这些参数运行查询,但它引发了相同的异常。原因是第二个参数 queue_aud0_.REVTYPE?,因为当 REVTYPE 为 smallint 时,hibernate 试图在那里设置 'DEL' 字符串。这很奇怪,因为这些表是由休眠自动生成的……知道为什么要这样做吗??
我使用的是 4.2.0.Final 版本
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>4.2.0.Final</version>
</dependency>
【问题讨论】:
-
它没有被绑定到一个字符串,而是一个枚举。 Hibernate 在日志中放置的是 Enum 的值,在这种情况下,您正在运行的
#getRevisions查询会过滤掉 REVTYPE=(2/DEL) 条目。至于查询失败的原因,也许该版本中的枚举处理存在问题。我假设您也在使用 hibernate-core 4.2.0.Final? -
是的,我在 Maven 依赖项中看到了 hibernate-core 4.2.0.Final(虽然我没有在 pom.xml 中设置它,所以我猜它是其他依赖项的子项)。反正真的很奇怪,因为审计写得很好,它把枚举值设置为数字,但是这个选择操作把它设置为字符串...
-
您是否可以尝试使用更新的版本? 4.2 版不再开发或维护。
-
谢谢。我玩了一点依赖,现在它可以工作了。我将 Hibernate 切换到 5.3.0.Final,将 SpringFramework 切换到 5.0.5.RELEASE 并删除了一些可能多余的 JPA 依赖项。它现在似乎工作了:)
标签: java postgresql hibernate hibernate-envers