Я работаю с 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: Unable to resolve path [Course.description], unexpected token [Course] [FROM model.Course WHERE Course.description LIKE '%a%' OR 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%';
в консоли IDEA SQL, он работает успешно. (Я не использую SELECT *
в создаваемом мной запросе, потому что HQL его не использует)
Я новичок в HQL и SQL, поэтому не знаю, в чем проблема.
Обновлено:
В режиме отладчика я нашел точное место, где вызывается исключение. Похоже, проблема с Hibernate:
Я не знаю, что вызывает эту проблему.
HQL работает с параметрами привязки, поэтому прямое добавление НРАВИТСЯ '% 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 варианта:
Создайте собственный SQL. session.createSQLQuery (...)
Критерии использования.
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();
ЧАЕВЫЕ:
НЕ СВЯЗЫВАЙТЕ СВОИ ПАРАМЕТРЫ. ИСПОЛЬЗОВАТЬ query.setParameter (..)
Добавьте псевдоним для объекта Course и укажите для него полный путь к классу