Как выбрать по max (id) из подзапроса в Hibernate Specification? - PullRequest
0 голосов
/ 29 мая 2018

У меня есть следующий код, который генерирует правильный запрос, за исключением того, что в sql отсутствует одно имя таблицы.

public List<Correspondence> findThreads(String userId, int page, int resultsPerPage) {
    Specification<Correspondence> spec = Specifications.<Correspondence>where((cor, query, cb) -> {
        Root<UserRegisterPerson> ur = query.from(UserRegisterPerson.class);
        Root<Correspondence> cor2 = query.from(Correspondence.class);
        return cb.and(
                cb.equal(ur.get("registerPersonNr"), cor.get("registerPersonNr")),
                cb.equal(ur.get("userId"), userId),
                cb.equal(cor.get("id"),
              // problem:
                query.subquery(Number.class).select(cb.max(cor2.get("id"))).where(cb.and(
                        cb.equal(cor2.get("applicationNumber"), cor.get("applicationNumber")),
                        cb.equal(cor2.get("dossierType"), cor.get("dossierType")),
                        cb.equal(cor2.get("registerPersonNr"), cor.get("registerPersonNr"))))));
    });
    return this.correspondenceRepository.findAll(spec, new PageRequest(page, resultsPerPage)).getContent();
}

Сгенерированный SQL с отсутствующим именем таблицы

select generatedAlias0
from 
    nl.boip.correspondencemodule.commons.database.entities.Correspondence as generatedAlias0, 
    nl.boip.correspondencemodule.commons.database.entities.UserRegisterPerson as generatedAlias1, 
    # the next line should actually be further below, where the table name is missing.
    nl.boip.correspondencemodule.commons.database.entities.Correspondence as generatedAlias2
where
    ( generatedAlias1.registerPersonNr=generatedAlias0.registerPersonNr ) 
    and ( generatedAlias1.userId=:param0 )
    and ( generatedAlias0.id=(
        select max(generatedAlias2.id)
        # See next line, the table name is missing
        from  where (
            generatedAlias2.applicationNumber=generatedAlias0.applicationNumber ) 
            and (generatedAlias2.dossierType=generatedAlias0.dossierType )
            and ( generatedAlias2.registerPersonNr=generatedAlias0.registerPersonNr )) )

Мой реальный случай более сложный, поэтому я не могу использовать CrudRepository для этого запроса (потому что поле сортировки на самом деле является параметром в моем вызове покоя)

1 Ответ

0 голосов
/ 04 июня 2018

Я думаю, вы должны указать .from для объекта подзапроса следующим образом:

public List<Correspondence> findThreads(String userId, int page, int resultsPerPage) {
    Specification<Correspondence> spec = Specifications.<Correspondence>where((cor, query, cb) -> {
        Root<UserRegisterPerson> ur = query.from(UserRegisterPerson.class);
        Subquery subQuery = query.subquery(Number.class);
        Root<Correspondence> cor2 = subQuery.from(Correspondence.class);
        return cb.and(
                cb.equal(ur.get("registerPersonNr"), cor.get("registerPersonNr")),
                cb.equal(ur.get("userId"), userId),
                cb.equal(cor.get("id"),
              // problem:
                subQuery.select(cb.max(cor2.get("id"))).where(cb.and(
                        cb.equal(cor2.get("applicationNumber"), cor.get("applicationNumber")),
                        cb.equal(cor2.get("dossierType"), cor.get("dossierType")),
                        cb.equal(cor2.get("registerPersonNr"), cor.get("registerPersonNr"))))));
    });
    return this.correspondenceRepository.findAll(spec, new PageRequest(page, resultsPerPage)).getContent();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...