关于java:HQL查询使用有效的SQL查询引发QueryException

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方法中用于通过descriptionname搜索Course的代码。

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();
}

请注意,在我收到的异常中,它表示我的方法实际上是在创建以下查询: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%';时,它成功运行。 (由于HQL未使用SELECT *,所以我不在正在创建的查询中使用SELECT *)

我是HQL和SQL的新手,所以我不知道问题出在哪里。

编辑:

在调试器模式下,我找到了调用异常的确切位置。 Hibernate似乎有问题:

The

我不知道是什么原因引起的。


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(..)