我正在使用 hibernate envers 5.2.17.Final 版本来存储和检索实体的审计历史记录,并在检索Category
实体的审计历史记录时出现以下异常。
这是我的Category
实体的样子。如您所见,NCRRule 使用NAME而不是主键Id映射到 Category 。
@Data
@Entity
@Table(name = TableNames.CATEGORY)
@Audited
@AuditTable(value = TableNames.CATEGORY_HISTORY)
public class Category {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "categoryGenerator")
@SequenceGenerator(name = "categoryGenerator", sequenceName = "GENERAL_CATEGORY_SQ", allocationSize = 1)
private long id;
@ManyToOne
@JoinColumn(name = "NCR_RULE", insertable = false, updatable = false, referencedColumnName = "NAME")
@Getter(onMethod = @__({@JsonIgnore, @Transient}))
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
private NCRRule ncrRule;
}
NCRRule
是未经审计的实体
@Entity
@Table(name= TableNames.NCR_RULE)
public class NCRRule implements Serializable {
@Id
@Column(name = "ID")
private Long id;
@Column(name = "NAME", unique = true)
private String ncrRuleName;
public Long getId() {
return id;
}
public String getNcrRuleName() {
return ncrRuleName;
}
}
异常堆栈跟踪如下:
2019-02-05 18:14:08 [http-nio-0.0.0.0-8899-exec-2] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [/risk-portal] threw exception [Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute query] with root cause
java.sql.SQLException: Fail to convert to internal representation
at oracle.jdbc.driver.CharCommonAccessor.getLong(CharCommonAccessor.java:258)
at oracle.jdbc.driver.T4CVarcharAccessor.getLong(T4CVarcharAccessor.java:562)
at oracle.jdbc.driver.GeneratedStatement.getLong(GeneratedStatement.java:228)
at oracle.jdbc.driver.GeneratedScrollableResultSet.getLong(GeneratedScrollableResultSet.java:620)
at oracle.jdbc.driver.GeneratedResultSet.getLong(GeneratedResultSet.java:1361)
at com.zaxxer.hikari.pool.HikariProxyResultSet.getLong(HikariProxyResultSet.java)
at org.hibernate.type.descriptor.sql.BigIntTypeDescriptor$2.doExtract(BigIntTypeDescriptor.java:63)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:261)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:247)
at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:333)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2868)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1747)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1673)
at org.hibernate.loader.Loader.getRow(Loader.java:1562)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:732)
at org.hibernate.loader.Loader.processResultSet(Loader.java:991)
at org.hibernate.loader.Loader.doQuery(Loader.java:949)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
at org.hibernate.loader.Loader.doList(Loader.java:2692)
at org.hibernate.loader.Loader.doList(Loader.java:2675)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507)
at org.hibernate.loader.Loader.list(Loader.java:2502)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:392)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1490)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414)
at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.buildAndExecuteQuery(AbstractAuditQuery.java:101)
at org.hibernate.envers.query.internal.impl.RevisionsOfEntityQuery.list(RevisionsOfEntityQuery.java:120)
at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.getResultList(AbstractAuditQuery.java:107)
at com.lch.grouprisk.riskportal.audit.query.AuditQueryUtils.getAuditQueryResults(AuditQueryUtils.java:34)
at com.lch.grouprisk.riskportal.audit.query.AuditQueryUtils.getHistories(AuditQueryUtils.java:55)
at audit.AuditHistoryRepositoryImpl.findByEntityId(AuditHistoryRepositoryImpl.java:20)
我尝试将in设置@AuditMappedBy(mappedBy = "ncrRuleName")
为实体,但在启动时出现异常。private NCRRule ncrRule;
Category
Caused by: org.hibernate.MappingException: @AuditMappedBy points to a property that doesn't exist: NCRRule.ncrRuleName
检索审计历史的代码是:
AuditQuery auditQuery = auditReader.createQuery()
.forRevisionsOfEntity(Category.class, false, true)
.add(AuditEntity.id().eq(entityId))
.addOrder(AuditEntity.revisionProperty("timestamp").asc());
List<AuditQueryResult<Category>> auditQueryResults = AuditQueryUtils.getAuditQueryResults(auditQuery, Category.class);