1

我在尝试让 Envers 执行我需要的查询时遇到了很大的问题。如果有人可以让我知道这是否可以从 Envers 内部实现,或者我是否需要直接执行 SQL,那将是一个巨大的帮助!

这是问题所在。我有一个虚构的“项目”实体——任何实体类都可以——已经过审计。我正在尝试通过 AuditReader 查询获取每个项目实体的最新版本。

当我这样做时(代码的其他部分无关紧要):

AggregatedAuditExpression maxExpression = AuditEntity.revisionNumber().maximize();
maxExpression.add(AuditEntity.id().eq("12345"));
query.add(maxExpression);

并打开 SQL 输出,我看到正在生成这个查询:

Hibernate: select project_a0_.id as id6_0_, project_a0_.REV as REV6_0_, auditrevis1_.id as id0_1_,
project_a0_.REVTYPE as REVTYPE6_0_, project_a0_.description as descript4_6_0_, 
auditrevis1_.timestamp     as timestamp0_1_, auditrevis1_.username as username0_1_ 
from MYSCHEMA.project_AUD project_a0_ cross join MYSCHEMA.REVINFO auditrevis1_ 
where project_a0_.REV=

(select max(project_a2_.REV) from MYSCHEMA.project_AUD project_a2_ 
               where project_a2_.id=?) 

and project_a0_.REV=auditrevis1_.id order by project_a0_.REV asc

注意“选择最大值”部分。这几乎正​​是我所需要的。只是 where 子句是错误的,我需要它说: where project_a2_.id=project_a0_.id

我手动编辑它,运行它,它工作得很好。现在它看起来像 IdMapper 类中的“addIdsEqualToQuery”方法让我做我想做的事。因此,如果我将 AuditEntity.id().eq("12345") 更改为:

maxExpression.add(new IdentifierIdsEqAuditExpression());

其中 IdentifierIdsEqAuditExpression 等于:

    class IdentifierIdsEqAuditExpression implements AuditCriterion {    
        @Override
        public void addToQuery(AuditConfiguration auditCfg, String entityName, QueryBuilder qb, Parameters parameters) {
            auditCfg.getEntCfg().get(entityName).getIdMapper()
                    .addIdsEqualToQuery(parameters, null, auditCfg.getAuditEntCfg().getOriginalIdPropName());
        }    
    }

它应该很接近 - 它是。我得到:

无效路径:'originalId.id' [select e__, r from com.mycompany.Project_AUD e_ , com.mycompany.audit.AuditRevisionEntity r where id = originalId.id and e _.originalId.REV.id = (select max(_e0 .originalId.REV.id) 来自 com.mycompany.Project_AUD e0 其中 id = originalId.id) 和 e _.originalId.REV.id = r.id order by e__.originalId.REV.id asc]

The problem is I can't get it to generate what I need and even if the prefix was changed from "originalId" to the correct one, why does envers start putting that all over the place, rather than in the single location?

4

1 回答 1

0

I'm afraid this is not currently possible with Envers. You would need to add something like parentIdEqual() to maxExpression, but there's no combinator like that.

Please open a feature request: https://hibernate.onjira.com/secure/Dashboard.jspa

As for the originalId, Envers entities have a composite id of the revision number and the original id (which is kept in the originalId sub-property).

于 2012-11-24T20:34:56.943 回答