问题描述
我试图让Envers执行我需要的查询时遇到了一个很大的问题。如果任何人都可以让我知道这是否可以从Envers中得到,或者我需要直接执行SQL,这将是一个巨大的帮助!
这是问题所在。我有一个化妆的项目实体 - 任何实体类都会这样做 - 它会被审核。我尝试通过AuditReader查询获取EVERY项目实体的最新版本。
当我这样做时(代码的其他部分应该不重要):
AggregatedAuditExpression maxExpression = AuditEntity.revisionNumber()。
maxExpression.add(AuditEntity.id()。eq(12345));
query.add(maxExpression);
并打开SQL输出,我看到正在生成这个查询:
'pre> 休眠:选择project_a0_.id如id6_0_,project_a0_.REV如REV6_0_,auditrevis1_.id如id0_1_,
project_a0_.REVTYPE如REVTYPE6_0_,project_a0_。描述作为descript4_6_0_,
auditrevis1_.timestamp如timestamp0_1_,auditrevis1_.username从MYSCHEMA.project_AUD project_a0_交叉联接MYSCHEMA.REVINFO auditrevis1_
username0_1_
其中project_a0_.REV =
(从MYSCHEMA.project_AUD project_a2_
选择最大(project_a2_.REV)其中project_a2_.id =?)
和project_a0_.REV = auditrevis1_.id为了通过project_a0_.REV ASC
请注意select max部分。这几乎正是我需要的。只是where子句是错误的我需要它说:
where project_a2_.id = project_a0_.id
我手工编辑它,运行它并且它工作完美。现在,像IdMapper类中的addIdsEqualToQuery方法让我做我想做的事情。因此,如果我使用以下方式更改AuditEntity.id()。eq(12345):
maxExpression.add(new IdentifierIdsEqAuditExpression());
其中IdentifierIdsEqAuditExpression等于:
类IdentifierIdsEqAuditExpression实现AuditCriterion {
@覆盖
公共无效addToQuery(AuditConfiguration auditCfg,字符串的entityName,QueryBuilder的QB,参数的参数){
auditCfg.getEntCfg()。得到(entityName).getIdMapper()
.addIdsEqualToQuery(parameters,null,auditCfg.getAuditEntCfg()。getOriginalIdPropName());
}
}
它应该接近 - 它是。我得到:
无效的路径:'originalId.id'[从com.mycompany.Project_AUD e_ 中选择e__,r,com.mycompany.audit.AuditRevisionEntity r其中id = originalId.id和e _。originalId.REV.id =(从com.mycompany.Project_AUD e0选择max(_e0.originalId.REV.id),其中id = originalId.id)和e _。originalId.REV.id = r.id order by e__.originalId.REV.id asc]
问题是我无法获得它产生我所需要的,即使前缀从originalId更改为正确的,为什么envers开始把所有的地方,而不是在一个位置?
恐怕目前Envers无法做到这一点。你需要添加像parentIdEqual()到maxExpression,但没有这样的combinator。
请打开一个功能请求:
I am having a huge problem trying to get Envers to execute the query I need. If anyone can let me know if this is possible from within Envers or if I need to excute the SQL directly that would be a tremendous help!
Here is the problem. I have a made-up "Project" entity - any Entity class will do - that is audited. I am trying to get the latest revision of EVERY Project entity via an AuditReader query.
When I do this (the other parts of the code shouldn't matter):
AggregatedAuditExpression maxExpression = AuditEntity.revisionNumber().maximize();
maxExpression.add(AuditEntity.id().eq("12345"));
query.add(maxExpression);
and turn on the SQL output, I see this query being generated:
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
Note the "select max" part. It is almost exactly what I need. Just the where clause is wrong I need it to say: where project_a2_.id=project_a0_.id
I edited it by hand, ran it and it works perfectly. Now it SEEMS like the "addIdsEqualToQuery" method in the IdMapper class lets me do what I want. So if I change out the AuditEntity.id().eq("12345") with this:
maxExpression.add(new IdentifierIdsEqAuditExpression());
where IdentifierIdsEqAuditExpression equals:
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());
}
}
it should be close - it is. I get:
Invalid path: '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) from com.mycompany.Project_AUD e0 where id = originalId.id) and 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?
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).
这篇关于hibernate能否返回特定类型的所有实体的最新版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!