JPA 2 + Критерии API + получить самый старый элемент в подзапросе - PullRequest
4 голосов
/ 23 сентября 2010

У меня есть две сущности (Dataset и Item), где первая содержит список последних.

@Entity
class Dataset {
    @Id long id;
    List<Item> items;
}

@Entity
class Item {
    @Id long id;
    @Temporal Date date;
    String someCriteria;
}

Я сейчас ищу любой набор данных , который ссылается на элемент с someCriteria = 'x' как самый старый элемент в списке набора данных (его дата до этого из всех других, упомянутых в этом наборе данных).

Это должно работать с Criteria API из JPA-2.0, но ответ, так как SQL-запрос тоже подойдет.

Вот как это выглядит сейчас:

Subquery<Item> _subquery = p_criteria.subquery(Item.class);
Root<Item> _itemRoot = _subquery.from(Item.class);
_subquery.select(_itemRoot);

// correlate
_subquery.correlate(_datsetRoot);

// type check
Predicate _typeP = p_builder.equal(_itemRoot.get(Item_.someCriteria), "x");

<additional predicates>
...

// reference check
_subquery.where(_typeP);

return p_builder.exists(_subquery);

Я думаю о создании подзапроса, упорядочить его по дате и проверить первый. К сожалению, JPA-2.0 не позволяет упорядочивать в подзапросах (или объединениях) (насколько я вижу). Моей второй идеей было получение MAX(date), которое должно поддерживаться большинством баз данных. То же самое и здесь, поддержка MAX, ABS, ... доступна только для номеров.

РЕДАКТИРОВАТЬ: Используя отсортированный подзапрос, он будет выглядеть так (MSSQL):

SELECT d.id
FROM Dataset d
WHERE EXISTS (
 SELECT TOP 1 *
 FROM Item i
 WHERE i.dataset_id = d.FALL_ID
    AND i.someCriteria = 'x'
 ORDER BY i.date
)
ORDER BY d.FALL_ID

(Как) я могу сделать это в JPA-2.0?

1 Ответ

6 голосов
/ 24 ноября 2010

В Java 1.6 есть методы CriteriaBuilder.least(expression) (вместо min()) и CriteriaBuilder.lessThanOrEqualTo(expressionA, expressionB) (вместо le()), которые работают для java.util.Date fields.

В Java 1.5, кажется, нет способа достичь этого без дополнительных полей в БД.

...