Решение JPA-запроса по поиску последней записи в списке подключенных - PullRequest
1 голос
/ 14 января 2009

Дается следующая структура класса:

class Job 
{
    String description;
    Collection<JobHistory> history;
}

class JobHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Эта структура класса доступна на БД через JPA. В DAO-Layer я могу писать запросы в синтаксисе JPA.

Проблема: мне нужен список с Job и JobHistory записями для данного владельца с данным идентификатором и который является последним в Jobhistory задания (заказано assignDate). Звучит довольно сложно, возможно, проще: дайте мне все задания и JobHistory, где указанный владелец является фактическим владельцем задания.

Обновление: для ясности немного изменю названия классов.

class Job 
{
    String description;
    Collection<JobOwnerHistory> history;
}

class JobOwnerHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

У каждого Job есть история его владельцев, отсортированная по assignDate. Фактический владелец получил работу, назначенную последним (т. Е. MAX(assignDate)). Я хочу найти для каждой работы запись JobOwnerHistory с MAX(assignDate) для конкретного пользователя User.

Ответы [ 2 ]

2 голосов
/ 24 января 2009

Я нашел следующий ответ на запрос:

SELECT j, h FROM Job j JOIN j.history h JOIN h.jobOwner u
WHERE u.name = :name AND 
    (SELECT MAX(h2.assignDate) FROM Job j2 JOIN j2.history h2
     WHERE h2 member of j.history) = h.assignDate

Самая важная часть в запросе - это подвыбор с MAX(h2.assignDate), потому что я хочу получить работу и самую новую запись в истории владельцев.

1 голос
/ 14 января 2009

Попробуйте:

SELECT j, j.history FROM Job j JOIN User u WHERE u.name = :name

Если бы я делал это в EclipseLink, я бы немного его изменил:

public List<Job> getAllJobsForUser(String username) {
  List<Job> jobs = entityManager
    .createQuery("SELECT j FROM Job j JOIN User u WHERE u.name = :name")
    .setParameter("name", username)
    .setHint(QueryHints.BATCH, "j.history")
    .queryForList();
}

Разница? В первой версии вы возвращаете два объекта, поэтому вам нужно извлечь их из массивов List или Object, тогда как во второй подсказка запроса просто загружает все истории заданий из (предположительно) ленивого отношения один ко многим .

Я не знаю, есть ли у Hibernate аналог этого. Toplink Essentials не имеет. Но это одна из моих любимых функций EclipseLink.

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

...