HQL query throws QueryException with working SQL query
我正在使用HSQLDB和Hibernate,并且我想从我的REST API执行搜索请求。
例如,对于诸如
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%']
这是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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(); } |
请注意,在我收到的异常中,它表示我的方法实际上是在创建以下查询:
当我在IDEA的SQL控制台中尝试
我是HQL和SQL的新手,所以我不知道问题出在哪里。
编辑:
在调试器模式下,我找到了调用异常的确切位置。 Hibernate似乎有问题:
我不知道是什么原因引起的。
HQL使用绑定参数,因此直接添加LIKE'%key%'无效。 Hibernate会将HQL转换为SQL,以实现您可以执行以下操作:
1 2 3 | for (; i < keyWords.length; i++) { sb.append(" OR" + colName +" LIKE" +"key" + String.valueOf(i));// notice that I'm not adding the '%%' } |
然后您必须绑定参数:
1 2 3 4 5 | 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(...)
使用条件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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(..)