Предложение JPQL ORDER BY с параметром

Я пытаюсь написать запрос JPQL с предложением ORDER BY:

query = "SELECT c FROM item ORDER BY c.name ASC"

Я хочу установить параметр «порядок», значение которого будет либо «ASC», либо «DESC»:

query = "SELECT c FROM item ORDER BY c.name :order"

А потом в моей реализации:

query.setParameter("order", "ASC");

Это когда я получаю ошибку гибернации:

org.hibernate.HibernateException: Errors in named queries

Есть идеи, что я делаю не так? Спасибо!


person Pierre Duplouy    schedule 01.09.2010    source источник


Ответы (4)


«ASC» или «DESC» не могут быть параметром запроса. Вместо этого вы можете использовать конкатенацию строк.

query = "SELECT c FROM item ORDER BY c.name " + sortOrder;

Вы должны убедиться, что содержимое sortOrder может быть только ASC или DESC и не исходит напрямую от пользователя.

person Mark Byers    schedule 01.09.2010
comment
Хорошо, это многое объясняет. Есть ли способ использовать конкатенацию строк в объявлении @NamedQuery? - person Pierre Duplouy; 01.09.2010

Если вы хотите использовать здесь именованные запросы, вам понадобятся два из них (именованные запросы статичны, и вы не можете использовать ASC и DESC в качестве параметров, как указано @Mark).

person Pascal Thivent    schedule 01.09.2010
comment
Или я мог бы просто использовать динамический запрос? - person Pierre Duplouy; 01.09.2010
comment
@Pedro Конечно. Но это не будет @NamedQuery (на самом деле я отвечал на один из ваших комментариев). - person Pascal Thivent; 01.09.2010
comment
Ты прав. Но правда в том, что у меня довольно много именованных запросов, которые нужно отсортировать, поэтому создание двух запросов для каждого приведет к вдвое большему количеству именованных запросов. Это проблема? Или лучше использовать динамические запросы? - person Pierre Duplouy; 01.09.2010
comment
С точки зрения обслуживания, определенно лучше использовать динамические запросы. Я бы так и поступил. - person Pascal Thivent; 01.09.2010

Вместо того, чтобы дважды писать именованный запрос, содержащий предложение 'order by', вы можете реализовать свой DAO следующим образом:

public List<MyEntity> findByAttribute(boolean desc,...){
    TypedQuery<MyEntity> q = em.createNamedQuery(...
    q.setParameter(...
    List<MyEntity> result = q.getResultList();
    if(desc){
        Collections.reverse(result );
    }
    return result;
}
person skay    schedule 09.11.2011
comment
Это может быть неприменимо, если pagination приходит в игру. - person Jin Kwon; 06.07.2012
comment
Просто примечание, чтобы сказать, что всегда лучше сортировать в базе данных, чем в коде, где это возможно. - person karol; 21.11.2016

Я полагаю, что правильный способ - использовать пункт ORDER BY в Criteria API

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Country> q = cb.createQuery(Country.class);
Root<Country> c = q.from(Country.class);
q.select(c);
q.orderBy(cb.asc(c.get("currency")), cb.desc(c.get("population")));
person Grigory Kislin    schedule 05.03.2019