我想实现一个spring数据方法,用于检查以下查询的结果
select count(1) from installation_requested_t requested
where requested.installation_id in
(select installation_id from installation_requested_t where request_id=?)
group by requested.installation_id
having count(1)>1;
对于项目,必须使用带有弹簧数据jpa的规范。 所以有我的存储库方法调用:
installationRequestedRepository.count(
InstallationSpecs
.existsInstallationRequestLinkedToAnotherEPR(movingEprId)
);
和我的规范方法:
public static Specification<InstallationRequested> existsInstallationRequestLinkedToAnotherEPR(final Long EPRId) {
return new Specification<InstallationRequested>() {
@Override
public Predicate toPredicate(Root<InstallationRequested> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Subquery<Long> InstallationIdsLinkedToEPRsubquery = query.subquery(Long.class);
InstallationIdsLinkedToEPRsubquery.select(root.get(InstallationRequested_.id))
.where(cb.equal(root.get(InstallationRequested_.environmentPermitRequestId), EPRId));
Subquery<InstallationRequested> installationRequestForTheseInstallationIdsWhoAreLinkedToAnotherEPR =
query.subquery(InstallationRequested.class);
installationRequestForTheseInstallationIdsWhoAreLinkedToAnotherEPR
.select(installationRequestForTheseInstallationIdsWhoAreLinkedToAnotherEPR
.from(InstallationRequested.class))
.where(root.get(InstallationRequested_.id).in(InstallationIdsLinkedToEPRsubquery))
.groupBy(root.get(InstallationRequested_.id))
.having(cb.greaterThan(cb.count(cb.literal(1)), cb.literal(1l)));
return cb.exists(installationRequestForTheseInstallationIdsWhoAreLinkedToAnotherEPR);
}
};
}
我的问题是一切都不能很好地执行:
org.springframework.dao.InvalidDataAccessApiUsageException:
org.hibernate.hql.internal.ast.QuerySyntaxException:
unexpected token: where near line 1, column 333
[select count(generatedAlias0) from be.question.domain.model.request.installation.InstallationRequested as generatedAlias0
where exists
(select generatedAlias1 from be.question.domain.model.request.installation.InstallationRequested as generatedAlias1
where generatedAlias0.id in
(select generatedAlias0.id from where generatedAlias0.environmentPermitRequestId=1072487L)
group by generatedAlias0.id having count(1)>1L)
];
您是否有想法让我的规范工作以及另一种方式来完成被询问的任务?
答案 0 :(得分:0)
我找到了解决问题的方法。 我修改了规范:
public static Specification<InstallationRequested> existsInstallationRequestLinkedToAnotherEPR(final Long EPRId) {
return new Specification<InstallationRequested>() {
@Override
public Predicate toPredicate(Root<InstallationRequested> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
// subquery to select installation ids
Subquery<Long> InstallationIdsLinkedToEPRsubquery = query.subquery(Long.class);
Root<InstallationRequested> selectIdSubQueryRoot =
InstallationIdsLinkedToEPRsubquery.from(InstallationRequested.class);
InstallationIdsLinkedToEPRsubquery
.select(selectIdSubQueryRoot.get(InstallationRequested_.installation).get(Installation_.id))
.where(cb.equal(selectIdSubQueryRoot.get(InstallationRequested_.environmentPermitRequestId),
EPRId));
// subquery to select count of installation request group by installation id
Subquery<Long> installationRequestForTheseInstallationIdsWhoAreLinkedToAnotherEPR =
query.subquery(Long.class);
Root<InstallationRequested> groupBySubQueryRoot =
installationRequestForTheseInstallationIdsWhoAreLinkedToAnotherEPR
.from(InstallationRequested.class);
Path<Long> installationIdInGroupBySubQuery =
groupBySubQueryRoot.get(InstallationRequested_.installation).get(Installation_.id);
installationRequestForTheseInstallationIdsWhoAreLinkedToAnotherEPR.select(cb.count(cb.literal(1)))
.where(installationIdInGroupBySubQuery.in(InstallationIdsLinkedToEPRsubquery))
.groupBy(installationIdInGroupBySubQuery)
.having(cb.greaterThan(cb.count(cb.literal(1)), cb.literal(1l)));
// returning existing condition on result of the group by
return cb.exists(installationRequestForTheseInstallationIdsWhoAreLinkedToAnotherEPR);
}
};
}
顺便说一句,如果有人作为一个更好的主意我会乐意阅读它;)