Порядок API критериев JPA по запросу для @EmbeddedId

У меня есть 2 класса:

@Entity
@Table(name = "DRCOMMENTS" ,schema = "XXX")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Drcomments.findAll", query = "SELECT d FROM Drcomments d"),
public class Drcomments implements Serializable {

private static final long serialVersionUID = 1L;

@EmbeddedId    
protected DrcommentsPK drcommentsPK;

@Size(max = 50)
@Column(name = "SDESC")
private String commentSecondaryCodeDescription;
}


@Embeddable
public class DrcommentsPK implements Serializable {

@Column(name = "CODE")
private Short commentPrimaryCode;

@NotNull   
@Column(name = "SCODE" , length=5)
private Short commentSecondaryCode;
}

Я пытаюсь создать запрос с динамическим порядком и параметром, например: я хочу выбрать все записи Drcomments, когда DrcommentsPK.commentPrimaryCode равен 1, а порядок будет DrcommentsPK.commentSecondaryCode. это то, что я пробовал:

        CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Drcomments> q = cb.createQuery(Drcomments.class);
    Root<Drcomments> c = q.from(Drcomments.class);

    q.select(c);
    q.where(cb.equal(c.get("drcommentsPK").get("commentPrimaryCode"), 1));

    Path<Drcomments> valuePath = c.get("drcommentsPK").get("commentSecondaryCode"); 
    Order[] orders; 
    if(sord.equals("desc"))
    {  
    orders = new Order[] {cb.desc(valuePath)};
    } 
    else
    {  
    orders = new Order[] {cb.asc(valuePath)};
    } 
    q.orderBy(orders);

    query = em.createQuery(q);                
    query.setFirstResult(start);
    query.setMaxResults(start + limit);   

    results = query.getResultList();

Проблема в том, что список результатов, который я получаю, не отсортирован в порядке описания commentSecondaryCode.

я делаю что-то не так? Как это может быть сделано? как создать запрос, который будет упорядочен по полю внутри класса emeddable?

ОБНОВЛЕНИЕ: это сгенерированный sql, который я получаю:

SELECT * FROM 
(SELECT * FROM 
(SELECT EL_TEMP.*, ROWNUMBER() OVER() AS EL_ROWNM FROM 
(SELECT CMSSDESC AS a1, CMSSCODE AS a4, CMSPCODE AS a5 FROM DRCOMMENTS
 WHERE (CMSPCODE = 1) ORDER BY CMSSCODE DESC, CMSPCODE DESC)
 AS EL_TEMP) 
 AS EL_TEMP2 WHERE EL_ROWNM <= 50) 
 AS EL_TEMP3 WHERE EL_ROWNM > 0

когда я запускаю этот код, он не возвращает записи в порядке описания CMSSCODE.. (поскольку порядок должен быть во внешнем выборе..) мне нужно что-то изменить в query.setFirstResult() и query.setMaxResults()? Как мне добавить его в конец запроса критериев, чтобы он был в последнем выборе?

Заранее спасибо.


person user590586    schedule 01.07.2012    source источник
comment
Как выглядит сгенерированный SQL? Возможно, вы найдете там хиты.   -  person Rasmus Franke    schedule 01.07.2012
comment
@Rasmus Franke: как я могу увидеть сгенерированное значение строки SQL?   -  person user590586    schedule 01.07.2012
comment
Это конфигурация, зависящая от поставщика, в вашем файле persistence.xml. Например, в спящем режиме просто добавьте <property name="hibernate.show_sql">true</property> в XML-файл сохранения.   -  person Rasmus Franke    schedule 01.07.2012
comment
@Rasmus Franke: я использую eclipseLink, но я получил сгенерированную строку SQL и обновил свой вопрос .. спасибо.   -  person user590586    schedule 01.07.2012
comment
SQL немного странный, так много подзапросов? Будет ли это работать, если вы пропустите части первого/максимального результата?   -  person Rasmus Franke    schedule 01.07.2012
comment
@Rasmus Franke: Это отлично работает, если я удалю части query.setFirstResult() и query.setMaxResults() ... но они мне нужны, так что это не вариант. Я тестировал sql, и проблема в sql даже с одним подвыбором. когда есть select from select и во внутреннем выборе есть порядок, результат не будет отсортирован. поэтому я думаю, что мне нужно добавить порядок после набора first/max, возможно ли это? спасибо.   -  person user590586    schedule 02.07.2012
comment
Глядя на ваш сгенерированный SQL, я думаю, что он должен возвращать строки по порядку. SELECT * FROM (x) не меняет порядок элементов, поэтому порядок во внутреннем запросе останется во внешних SELECT. Ваш сгенерированный SQL выглядит так же, как официальный пример на wiki.eclipse.org/EclipseLink/Examples/ JPA/разбиение на страницы . Возможно, ваша проблема кроется в другом? Вы уверены, что объекты действительно не отсортированы?   -  person Rasmus Franke    schedule 02.07.2012
comment
@Расмус Франке: я обнаружил, что для сортировки результатов мне нужно добавить order by filed_name desc в over(). Могу ли я сделать это с моим текущим CriteriaQuery? как это можно добавить в запрос? еще раз спасибо.   -  person user590586    schedule 11.07.2012
comment
Что такое over()? Вы просто хотите отсортировать по другому полю?   -  person Rasmus Franke    schedule 11.07.2012


Ответы (1)


Ваш код в порядке и соответствует стандарту. Если вы уверены, что это не работает, значит, это ошибка в реализации или какие-то странности в тех частях кода, которые не показаны. Например, убедитесь, что значение sord точно равно "desc" (с учетом регистра), потому что в противном случае вы будете использовать возрастающий порядок.

Я пробовал это с Hibernate 3.6.8.Final и EclipseLink (2.3.2). С обоими он работает как положено - ORDER BY SCODE [ASC/DESC] является частью выполняемого SQL-запроса.

person Mikko Maunu    schedule 01.07.2012
comment
Я проверил значение sord, и все в порядке, но я обновил свой вопрос сгенерированной строкой sql. спасибо. - person user590586; 01.07.2012
comment
Запрос вроде правильный. Можете ли вы привести пример фактического и ожидаемого результата? - person Mikko Maunu; 03.07.2012
comment
Я обнаружил, что для того, чтобы отсортировать результат, мне нужно добавить порядок по описанию filed_name в over(). Могу ли я сделать это с моим текущим CriteriaQuery? как это можно добавить в запрос? еще раз спасибо. - person user590586; 11.07.2012