Inner Joins Query в HQL
Я не могу выполнить HQL для внутренних объединений, Query выполняется правильно в sql, но не в HQL. Я не знаю, где я скучаю. Ваша помощь ощутима.
***Error***: org.hibernate.hql.ast.QuerySyntaxError: unexpected token: ON near line 1, column 148 [SELECT op.username, op.email, orders.p_id, orders.o_id, product.listed_price FROM com.model.Orders orders INNER JOIN orders.OrderProcessing as op ON op.u_id = orders.u_id INNER JOIN orders.Product as product ON product.p_id = orders.p_id WHERE product.p_id = '208' ORDER BY op.username]
productList = (List<Orders>) session.createQuery(
"SELECT op.username, op.email, orders.p_id, orders.o_id, product.listed_price " +
"FROM Orders orders " +
"INNER JOIN orders.OrderProcessing as op " +
"ON op.u_id = orders.u_id " +
"INNER JOIN orders.Product as product " +
"ON product.p_id = orders.p_id " +
"WHERE product.p_id = '"+p_id +"' " +
"ORDER BY op.username"
).list();
4 ответа
Соединения в HQL имеют немного другой синтаксис.
Если вы уже сопоставили эти ассоциации с Hibernate, условия соединения (которые id
Поля, для которых выполняется соединение, обычно обрабатываются самой Hibernate (которая уже имеет эту информацию, определенную в отображении), поэтому вам нужно только указать, с каким атрибутом сопоставляется ассоциация, и выполнить соединение для него:
SELECT op.username, op.email, orders.p_id, orders.o_id, product.listed_price
FROM Orders order
INNER JOIN order.orderProcessing as op
INNER JOIN order.product as product
ORDER BY op.username
В случае, если эти ассоциации не сопоставлены, вам, вероятно, следует использовать перекрестное соединение, подобное синтаксису, и указать условия соединения в WHERE
пункт. Обратите внимание, что это может оказать негативное влияние на эффективность в зависимости от структуры вашей схемы и СУБД.
SELECT op.username, op.email, orders.p_id, orders.o_id, product.listed_price
FROM Orders order, OrderProcessing op, Product product
WHERE op.u_id = order.u_id AND product.p_id = orders.p_id
ORDER BY op.username
Вы можете найти больше информации о соединениях HQL в 14.3. Ассоциация и присоединение раздела Hibernate.
Объединения в HQL не работают, как в SQL. Вы можете присоединиться к ассоциации:
select order_1.code, item.code, item.quantity
from Order order_1 inner join order_1.item item;
или используйте выбор из нескольких таблиц:
select order_1.code, item.code, item.quantity
from Order order_1, Item item where item.order=order_1;
любой синтаксис имеет свои преимущества и недостатки, поэтому вы должны выбирать в зависимости от ситуации.
Стоит отметить, что существует также неявная нотация, из-за которой вообще не нужно использовать соединение:
select item.order.code, item.code, item.quantity from Item item;
Я подозреваю, что это потому, что order
это зарезервированное слово (как в order by
). Попробуй сделать FROM Orders o
вместо.
Думаю, у тебя тоже будут другие проблемы.
Посмотрите, что вы выбираете (набор случайных значений столбцов), и что вы ожидаете, что Hibernate вернет вас (List<Orders>
).
Я ожидаю, что ты не вернешься List<Orders>
потому что структура вашего запроса заставит спящий режим в SQL
режим вместо HQL
, В этом режиме вы просто получите обратно List<Object[]>
где каждый Object[]
это набор из тех четырех столбцов, которые вы выбираете.
Эта ссылка объясняет, что вы можете ожидать от различных запросов:
Я предлагаю использовать ссылки на связанные объекты .
В SQL вы часто будете объединять таблицы для поиска результатов по связанным сущностям. В JPQL вы можете ссылаться на значение связанных сущностей, обращаясь к ним непосредственно как к атрибутам сущностей в запросе.
private static final String FIND_ORDERS_WITH_PRODUCTS =
"from Order o " +
"where :product member of o.products";
Обратите внимание, что Order — это класс сущности, а products — связанный список.
то вы можете использовать его в своем методе следующим образом:
List<Order> findOrders(Outfit o){
TypedQuery<Order> query = entityManager.createQuery(FIND_ORDERS_WITH_PRODUCTS, Order.class);
query.setParameter("outfit", o);
return query.getResultList();
}