HQL 查询抛出 QueryException 与工作 SQL 查询
HQL query throws QueryException with working SQL query
我正在使用 HSQLDB 和 Hibernate,我想从我的 REST API.
执行搜索请求
例如,对于像 localhost:8080/search?token=a%20e
这样的 REST 请求,我的方法应该创建以下查询: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
中通过 description
或 name
搜索 Course
的方法中的代码。
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%'
当我在 IDEA 的 SQL 控制台中尝试 SELECT * FROM Course WHERE c.description LIKE '%a%' OR c.DESCRIPTION LIKE '%e%';
时,它运行成功。 (我在创建的查询中没有使用 SELECT *
,因为 HQL 不使用它)
我是 HQL 新手,SQL,所以我不知道问题出在哪里。
编辑:
在调试器模式下,我找到了调用异常的确切位置。 Hibernate 似乎有问题:
我不知道是什么导致了这个问题。
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] + "%")
}
如您所见,一个简单的查询有很多代码。
所以基本上你有两个选择:
创建原生 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(..)
我正在使用 HSQLDB 和 Hibernate,我想从我的 REST API.
执行搜索请求例如,对于像 localhost:8080/search?token=a%20e
这样的 REST 请求,我的方法应该创建以下查询: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
中通过 description
或 name
搜索 Course
的方法中的代码。
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%'
当我在 IDEA 的 SQL 控制台中尝试 SELECT * FROM Course WHERE c.description LIKE '%a%' OR c.DESCRIPTION LIKE '%e%';
时,它运行成功。 (我在创建的查询中没有使用 SELECT *
,因为 HQL 不使用它)
我是 HQL 新手,SQL,所以我不知道问题出在哪里。
编辑:
在调试器模式下,我找到了调用异常的确切位置。 Hibernate 似乎有问题:
我不知道是什么导致了这个问题。
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] + "%")
}
如您所见,一个简单的查询有很多代码。
所以基本上你有两个选择:
创建原生 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(..)