Я новичок в Hibernate. Я установил OneToMany отображение между User и Expense. Я пытаюсь вернуть расходы на User за last week. Это запрос MySQL, который я использую.

select SUM(amount) from Expense INNER JOIN User ON Expense.user_id = User.id AND User.username ='testUser' WHERE created >= curdate() - INTERVAL DAYOFWEEK(curdate())+1 DAY AND created < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY;

Когда я пытаюсь использовать этот запрос в спящем режиме, я получаю HibernateQueryException

 String query = "select SUM(amount) from Expense INNER JOIN User ON Expense.user_id = User.id AND user.username ='sarvam' WHERE created >= curdate() - INTERVAL DAYOFWEEK(curdate())+1 DAY AND created < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY";
 List list = session.createQuery(query).list();

Я получаю ошибку

Exception in thread "main" org.hibernate.QueryException: outer or full join must be followed by path expression [select SUM(amount) from com.challenge.pojo.Expense INNER JOIN User ON Expense.user_id = User.id AND user.username ='sarvam' WHERE created >= curdate() - INTERVAL DAYOFWEEK(curdate())+1 DAY AND created < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY]
    at org.hibernate.QueryException.generateQueryException(QueryException.java:120)
    at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
    at org.hibernate.hql.internal.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:233)
    at org.hibernate.hql.internal.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:193)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150)
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:298)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1825)
    at com.challenge.dao.ExpenseDAO.getExpensesForLastWeek(ExpenseDAO.java:52)
    at com.challenge.dao.ExpenseDAO.getExpensesForLastWeek(ExpenseDAO.java:44)
    at com.challenge.dao.Test.main(Test.java:27)
Caused by: org.hibernate.QueryException: outer or full join must be followed by path expression
    at org.hibernate.hql.internal.classic.FromParser.token(FromParser.java:253)
    at org.hibernate.hql.internal.classic.ClauseParser.token(ClauseParser.java:93)
    at org.hibernate.hql.internal.classic.PreprocessingParser.token(PreprocessingParser.java:118)
    at org.hibernate.hql.internal.classic.ParserHelper.parse(ParserHelper.java:43)
    at org.hibernate.hql.internal.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:223)
    ... 10 more

Может кто-нибудь, пожалуйста, помогите мне исправить это.

1
Newbie 29 Май 2017 в 02:13

2 ответа

Лучший ответ

createQuery (String queryString) Создать новый экземпляр Query для заданной строки запроса HQL.

createSQLQuery (String queryString) Создайте новый экземпляр SQLQuery для данной строки запроса SQL.

Вы используете первый, который ожидает HQL в качестве входных данных, для использования нативного SQL вы должны использовать второй.

String query = "select SUM(amount) from Expense INNER JOIN User ON Expense.user_id = User.id AND user.username ='sarvam' WHERE created >= curdate() - INTERVAL DAYOFWEEK(curdate())+1 DAY AND created < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY";
List list = session.createSQLQuery(query).list();

Сессионная документация

1
J-Alex 28 Май 2017 в 23:21

Возможно, вы захотите взглянуть на: Я не могу сделать внутреннее соединение между двумя таблицами в hibernate hql query

Если вы используете HQL, вы должны использовать их объектно-ориентированный стиль, который может выглядеть примерно так:

String query = "select SUM(amount) from Expense exp INNER JOIN User u ON e.user_id = u.id AND u.username = 'sarvam' ...";
List list = session.createQuery(query).list();

( Непроверенные)

В качестве альтернативы вы можете продолжать использовать стандартный синтаксис SQL, если вместо этого используете:

List list = session.createSQLQuery(query).list();

Тогда вы можете прочитать главу 16 документации по гибернации.

Имейте в виду, что диалект SQL зависит от базовой базы данных. В зависимости от вашего приложения в другой системе может использоваться другая база данных, которая может нарушить ваши операторы SQL.

0
qwerty 28 Май 2017 в 23:53