ВНУТРЕННЯЯ РЕШЕНИЕ проблема с 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)
;