ВНУТРЕННЯЯ РЕШЕНИЕ проблема с JPQL (даже если запрос SQL работает)

"добрый день" (привет всем)

Я пришел из этой темы: Как я могу выбрать строки с MAX(значение столбца), DISTINCT по другому столбцу в SQL?

Этот парень делает почти то, что мне нужно в моем проекте. На самом деле, я пытаюсь сделать что-то вроде Git: получить все экземпляры в их последней версии. В настоящее время у меня есть таблица "UM", с такими атрибутами:

  • int id (первичный ключ, автоматически сгенерированный)
  • Строковое имя (может быть продублировано)
  • версия int (1, 2, 3, [...])
  • Строка ФМР
  • [другие атрибуты, не используемые в этом случае]

У меня также есть этот запрос в SQL (который работает хорошо и получает желаемый результат):

SELECT * FROM agrid.um AS u INNER JOIN
        (SELECT u2.name, max(u2.version) AS MaxVersion, u2.fmr
         FROM agrid.um AS u2 WHERE u2.fmr = 'CZ2ABVIMG0000' GROUP BY u2.name, u2.fmr) umVersion
         ON u.name = umVersion.name AND u.version = umVersion.MaxVersion
         WHERE u.fmr = 'ABCDE';

Но когда я попытался сделать то же самое в JPQL, у меня есть некоторые ошибки "JOIN":

TypedQuery<UmEty> q = getManager().getEntityManager().createQuery(
            "SELECT u FROM UmEty u INNER JOIN"
            + " (SELECT u2.name, max(u2.version) AS MaxVersion, u2.fmr "
            + " FROM UmEty u2 WHERE u2.fmr = :fmr GROUP BY u2.name, u2.fmr) umVersion"
            + " ON u.name = umVersion.name AND u.version = umVersion.MaxVersion WHERE u.fmr = :fmr", UmEty.class);
    q.setParameter("fmr", fmr);
    return q.getResultList();

Со следующим исключением:

Exception Description: Syntax error parsing
[SELECT u FROM UmEty u INNER JOIN (SELECT u2.name, max(u2.version)
AS MaxVersion, u2.fmr 
FROM UmEty u2 WHERE u2.fmr = :fmr GROUP BY u2.name, u2.fmr) umVersion
ON u.name = umVersion.name
AND u.version = umVersion.MaxVersion WHERE u.fmr = :fmr].
[33, 147] The join association path is not a valid expression.

Я также пытался просто использовать "JOIN" вместо "INNER JOIN" и некоторые другие тесты (удалить предложение "WHERE", ...), но у меня всегда выбрасывается это исключение. Я не очень знаком с JPQL и уже прочитал тему "INNER JOIN" на Objectdb (==> https://www.objectdb.com/java/jpa/query/jpql/from). Но даже с этой информацией, я не могу получить успешный запрос

Может кто-нибудь сказать мне, почему мой перевод SQL-запроса в JPQL не работает?

Заранее спасибо:)

1 ответ

Чтобы объединение работало в JPQL, вы должны иметь прямую зависимость в графе объектов от сущности, к которой хотите присоединиться.

Этот пример взят из самой спецификации:

SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1

где Customer это субъект, имеющий отношение к Order сущность через customer.orders список объектов.

Вы можете прочитать больше о соединениях в главе 4.4.5 Java Persistence Spec.

РЕДАКТИРОВАТЬ:

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

select * from agrid.um u where u.fmr = 'ABCDE' and not exists (select * from agrid.um u2 where u.name = u2.name and u.version < u2.version) ;

Другие вопросы по тегам