问题
I want to implement a spring data method which check result of the following query
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;
For the project, it is mandatory to use specification with the spring data jpa. So there is my repository method call :
installationRequestedRepository.count(
InstallationSpecs
.existsInstallationRequestLinkedToAnotherEPR(movingEprId)
);
and my spec method:
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);
}
};
}
And my problem is that everything doesn't execute well:
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)
];
Do you have an idea to make my spec work and another way to make the asked task ?
回答1:
I found a solution to my problem. I fix the specification:
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);
}
};
}
By the way, if someone as a better idea i would be happy to read it ;)
来源:https://stackoverflow.com/questions/49007656/using-group-by-with-specification-in-spring-data-count-method