Решение запроса JPA для поиска последней записи в подключенном списке

StackOverflow https://stackoverflow.com/questions/442488

  •  22-07-2019
  •  | 
  •  

Вопрос

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

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

class JobHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Эта структура классов доступна в базе данных через JPA.На уровне DAO я могу писать запросы в синтаксисе 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.

Это было полезно?

Решение

Пытаться:

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.

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

Другие советы

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

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) , потому что я хочу получить работу и самую новую запись в истории владельцев .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top