HQL-запрос выдает QueryException с рабочим SQL-запросом - PullRequest
0 голосов
/ 01 мая 2018

Я работаю с HSQLDB и Hibernate и хочу выполнять поисковые запросы из моего REST API.

Например, для запроса REST, например localhost:8080/search?token=a%20e, мой метод должен создать следующий запрос: FROM Course WHERE Course.description LIKE '%a%' OR Course.description LIKE '%e%', и я получаю это исключение:

javax.servlet.ServletException: java.lang.IllegalArgumentException: org.hibernate.QueryException: невозможно разрешить путь [Course.description], неожиданный токен [Course] [ОТ модели.Course WHERE Course.description LIKE '% a% 'ИЛИ Course.description LIKE'% e% ']

Это код в SearchService методе поиска Course по description или name.

public List<Course> searchCourses(String token, MatchIn column) {

    // Prepare and clean token, leaving only key words

    String[] keyWords = token.split(" ");

    // Build query and ask database to retrieve relevant courses

    StringBuilder sb = new StringBuilder("FROM Course WHERE ");
    String colName = "Course.";
    if(column.equals(MatchIn.DESCRIPTION))  colName += "description";
    else if(column.equals(MatchIn.NAME))  colName += "name";
    sb.append(colName);

    int i = 0;

    sb.append(" LIKE \'");
    sb.append("%");
    sb.append(keyWords[i]);
    sb.append("%\'");

    if(keyWords.length != 1){
        i++;

        for (; i < keyWords.length; i++) {
            sb.append(" OR " + colName +
                    " LIKE \'");
            sb.append("%");
            sb.append(keyWords[i]);
            sb.append("%\'");
        }
    }

    Query query = session.createQuery(sb.toString());

    return query.list();
}

Обратите внимание, что в полученном исключении говорится, что мой метод фактически создает следующий запрос: FROM *model.*Course WHERE Course.description LIKE '%a%' OR Course.description LIKE '%e%'

Когда я пытаюсь SELECT * FROM Course WHERE c.description LIKE '%a%' OR c.DESCRIPTION LIKE '%e%'; в консоли SQL IDEA, он работает успешно. (Я не использую SELECT * в создаваемом запросе, потому что HQL его не использует)

Я новичок в HQL и SQL, поэтому не знаю, в чем проблема.

EDIT:

В режиме отладчика я нашел точное место, где вызывается исключение. Кажется, есть проблема с Hibernate:

The call of Session.createQuery(String queryString)

Я не знаю, что является причиной этой проблемы.

1 Ответ

0 голосов
/ 02 мая 2018

HQL работает с параметрами привязки, поэтому добавление напрямую LIKE '% key%' не будет работать. Hibernate преобразует HQL в SQL, поэтому для этого вы можете сделать следующее:

for (; i < keyWords.length; i++) {
    sb.append(" OR " + colName + " LIKE " + "key" + String.valueOf(i));// notice that I'm not adding the '%%'
}

тогда вам нужно привязать параметры:

 Query query = session.createQuery(sb.toString());

 for (int j = 0; j < keyWords.length; j++) {
    query.setParameter("key" + String.valueOf(j), "%" + keyWords[j] + "%")
}

Как видите, кода для простого запроса много.

Так что в основном у вас есть 2 варианта:

  1. Создать собственный SQL. session.createSQLQuery (...)

  2. Использовать критерии.

    String colName = "";
    
    if(column.equals(MatchIn.DESCRIPTION)) {
        colName = "description";
    } else if(column.equals(MatchIn.NAME)) {
        colName = "name";
    }
    
    Criteria criteria = session.createCriteria(Course.class)
    
    for(String key : keyWords) {
        criteria.add(Restrictions.or(Restrictions.like( colName, "%" + key + "%"));
    }
    
    return criteria.list();
    

СОВЕТЫ: ​​

НЕ ОБРАЩАЙТЕСЬ К ВАШИМ ПАРАМ. USE query.setParameter (..)

...