Выберите отличные с порядком по запускам OK при копировании в БД, но не при запуске из приложения - PullRequest
1 голос
/ 04 июня 2019

У меня есть запрос, который выполняется нормально, когда я копирую его из консоли приложения, но не выполняется с ошибкой в ​​приложении: вызвано: org.postgresql.util.PSQLException: ОШИБКА: для SELECT DISTINCT выражения ORDER BY должны появляться в selectсписок.

Но когда я смотрю на запрос, я вижу, что столбец, по которому я упорядочиваю, находится в списке выбора.

Метод, который создает запрос по спецификации (уведомление упорядочено по и отличается)

   private CriteriaQuery<Tuple> createSearchQuery(Specification<Node> spec, String searchQuery) {
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();

        CriteriaQuery<Tuple> queryForNode = builder.createTupleQuery();
        Root<Node> nodeRoot = queryForNode.from(Node.class);
        Join<Node,FTSDocument> join = nodeRoot.join(Node_.document);

        Expression orderyBy = builder.function(
            "ts_rank",
            Double.class,
            builder.function("to_tsvector", Object.class, join.get(FTSDocument_.document)),
            builder.function("plainto_tsquery",Object.class,builder.literal(searchQuery))
        );

        queryForNode
            .multiselect(nodeRoot, orderyBy)
            .distinct(true)
            .where(spec.toPredicate(nodeRoot, queryForNode, builder))
            .orderBy(builder.desc(orderyBy));
        return queryForNode;
    }

Основной метод:

    public Page<Node> findDistinctBySpec(Specification<Node> spec, String searchQuery, Pageable pageable) {

        // Get page content
        List<Tuple> resultList = entityManager.createQuery(createSearchQuery(spec, searchQuery))
            .setFirstResult(pageable.getPageNumber() * pageable.getPageSize())
            .setMaxResults(pageable.getPageSize())
            .getResultList();

        List<Node> nodes = resultList.stream().map(tuple-> tuple.get(0,Node.class)).collect(Collectors.toList());

        // Get total count of matched results
        TypedQuery<Long> typedQueryForCount = entityManager.createQuery(createCountQuery(spec));
        Long totalCount = typedQueryForCount.getSingleResult();

        return new PageImpl<>(nodes, pageable, totalCount);
    }

Сгенерированный запрос находится ниже, и когда я копирую его в базу данных и задаю все параметры вместо вопросительных знаков - он работает нормально.Hibernate:

    select
        distinct node0_."id" as col_0_0_,
        ts_rank(to_tsvector(ftsdocumen1_."document"),
        plainto_tsquery(?)) as col_1_0_,
        node0_."id" as id1_7_,
        node0_."created_by" as created_2_7_,
        node0_."created_date" as created_3_7_,
        node0_."last_modified_by" as last_mod4_7_,
        node0_."last_modified_date" as last_mod5_7_,
        node0_."alias" as alias6_7_,
        node0_."description" as descript7_7_,
        node0_."image_url" as image_ur8_7_,
        node0_."left" as left9_7_,
        node0_."name" as name10_7_,
        node0_."right" as right11_7_,
        node0_."space_id" as space_i14_7_,
        node0_."state" as state12_7_,
        node0_."type" as type13_7_,
        node0_."user_group_id" as user_gr15_7_ 
    from
        "node" node0_ 
    left outer join
        "node_document" ftsdocumen1_ 
            on node0_."id"=ftsdocumen1_."id" 
    left outer join
        "user_group" usergroup2_ 
            on node0_."user_group_id"=usergroup2_."id" 
    left outer join
        "user_user_group" users3_ 
            on usergroup2_."id"=users3_."user_group_id" 
    left outer join
        "jhi_user" user4_ 
            on users3_."user_id"=user4_."id" 
    inner join
        "space" space5_ 
            on node0_."space_id"=space5_."id" 
    where
        space5_."state"=0 
        and node0_."state"=0 
        and (
            node0_."user_group_id" is null 
            or user4_."login"=?
        ) 
        and 1=1 
        and to_tsvector('english', document ) @@ plainto_tsquery( ? )=true 
    order by
        ts_rank(to_tsvector(ftsdocumen1_."document"),
        plainto_tsquery(?)) desc limit ?

Вот журнал базы данных postresql:

2019-06-04 13:23:16.282 EEST [6820] LOG:  execute <unnamed>: BEGIN
select distinct node0_."id" as col_0_0_, ts_rank(to_tsvector(ftsdocumen1_."document"), plainto_tsquery($1)) as col_1_0_, node0_."id" as id1_7_, node0_."created_by" as created_2_7_, node0_."created_date" as created_3_7_, node0_."last_modified_by" as last_mod4_7_, node0_."last_modified_date" as last_mod5_7_, node0_."alias" as alias6_7_, node0_."description" as descript7_7_, node0_."image_url" as image_ur8_7_, node0_."left" as left9_7_, node0_."name" as name10_7_, node0_."right" as right11_7_, node0_."space_id" as space_i14_7_, node0_."state" as state12_7_, node0_."type" as type13_7_, node0_."user_group_id" as user_gr15_7_ from "node" node0_ inner join "node_document" ftsdocumen1_ on node0_."id"=ftsdocumen1_."id" left outer join "user_group" usergroup2_ on node0_."user_group_id"=usergroup2_."id" left outer join "user_user_group" users3_ on usergroup2_."id"=users3_."user_group_id" left outer join "jhi_user" user4_ on users3_."user_id"=user4_."id" inner join "space" space5_ on node0_."space_id"=space5_."id" where space5_."state"=0 and node0_."state"=0 and (node0_."user_group_id" is null or user4_."login"=$2) and 1=1 and to_tsvector('english', document ) @@ plainto_tsquery( $3 )=true order by ts_rank(to_tsvector(ftsdocumen1_."document"), plainto_tsquery($4)) desc limit $5 node0_."id" as col_0_0_, ts_rank(to_tsvector(ftsdocumen1_."document"), plainto_tsquery($1)) as col_1_0_, node0_."id" as id1_7_, node0_."created_by" as created_2_7_, node0_."created_date" as created_3_7_, node0_."last_modified_by" as last_mod4_7_, node0_."last_modified_date" as last_mod5_7_, node0_."alias" as alias6_7_, node0_."description" as descript7_7_, node0_."image_url" as image_ur8_7_, node0_."left" as left9_7_, node0_."name" as name10_7_, node0_."right" as right11_7_, node0_."space_id" as space_i14_7_, node0_."state" as state12_7_, node0_."type" as type13_7_, node0_."user_group_id" as user_gr15_7_ from "node" node0_ inner join "node_document" ftsdocumen1_ on node0_."id"=ftsdocumen1_."id" left outer join "user_group" usergroup2_ on node0_."user_group_id"=usergroup2_."id" left outer join "user_user_group" users3_ on usergroup2_."id"=users3_."user_group_id" left outer join "jhi_user" user4_ on users3_."user_id"=user4_."id" inner join "space" space5_ on node0_."space_id"=space5_."id" where space5_."state"=0 and node0_."state"=0 and (node0_."user_group_id" is null or user4_."login"=$2) and 1=1 and to_tsvector('english', document ) @@ plainto_tsquery( $3 )=true order by ts_rank(to_tsvector(ftsdocumen1_."document"), plainto_tsquery($4)) desc limit $5
2019-06-04 13:23:16.323 EEST [6820] LOG:  execute S_3: ROLLBACK

Я проследил его до отправки Hickari, которая прекрасно работает при копировании в базу данных без каких-либо изменений в запросе!

select distinct node0_."id" as col_0_0_,
 ts_rank(to_tsvector(ftsdocumen1_."document"), plainto_tsquery('super')) as col_1_0_,
 node0_."id" as id1_7_,
 node0_."created_by" as created_2_7_,
 node0_."created_date" as created_3_7_,
 node0_."last_modified_by" as last_mod4_7_,
 node0_."last_modified_date" as last_mod5_7_,
 node0_."alias" as alias6_7_,
 node0_."description" as descript7_7_,
 node0_."image_url" as image_ur8_7_,
 node0_."left" as left9_7_,
 node0_."name" as name10_7_,
 node0_."right" as right11_7_,
 node0_."space_id" as space_i14_7_,
 node0_."state" as state12_7_,
 node0_."type" as type13_7_,
 node0_."user_group_id" as user_gr15_7_ 
 from "node" node0_ 
 inner join "node_document" ftsdocumen1_ on node0_."id"=ftsdocumen1_."id" 
 left outer join "user_group" usergroup2_ on node0_."user_group_id"=usergroup2_."id" 
 left outer join "user_user_group" users3_ on usergroup2_."id"=users3_."user_group_id" 
 left outer join "jhi_user" user4_ on users3_."user_id"=user4_."id" inner join "space" space5_ on node0_."space_id"=space5_."id" 
 where space5_."state"=0 and node0_."state"=0 and (node0_."user_group_id" is null or user4_."login"='firstname.lastname') and 1=1 and 
 to_tsvector('english', document ) @@ plainto_tsquery( 'super' )=true 
 order by ts_rank(to_tsvector(ftsdocumen1_."document"), plainto_tsquery('super')) desc limit 30

1 Ответ

0 голосов
/ 05 июня 2019

Здесь люди говорят, что это ошибка Hibernate, когда порядок с параметром не работает, и это должно быть исправлено в версии 6.

Между тем решение, которое работало для меня, было заказомпо номеру столбца в списке выбора вот так:

.orderBy(builder.desc(builder.literal(2)));
...