Hibernate中连续命名的参数问题(Spring HibernateTemplate)

时间:2011-07-01 14:26:04

标签: java sql hibernate spring parameters

我正在尝试使用命名参数将一些字符串注入查询中。我正在使用spring和hibernateTemplate,而且我对Hibernate还不熟悉。我已经获得了未命名和命名的参数,但似乎当它们彼此相邻时会抛出错误。我在下面的问题中做了类似的示例代码(简化以突出显示手头的问题)。 orderBy包含字段的字符串,orderDirection包含ASC或DESC。

public List<HashMap<String, Object>> exampleList(String orderBy, String orderDirection) {
    logger.debug(orderBy);
    logger.debug(orderDirection);

    final String queryString =  "SELECT new map("+
                                "a.id AS id, "+
                                "a.name AS name, "+
                                "a.number AS number ) "+
                                "FROM Asset a "+
                                "ORDER BY :orderBy :orderDirection";

    String[] parameterNames = {"orderBy", "orderDirection"};
    Object[] parameterValues = {orderBy, orderDirection};

    List<HashMap<String, Object>> results = (List<HashMap<String, Object>>) hibernateTemplate.find(queryString, parameterNames, parameterValues);

    return results;
}

控制台调试我的参数:

DEBUG: com.myOrg.myProject.asset.AssetDAO - a.id
DEBUG: com.myOrg.myProject.asset.AssetDAO - desc

我知道这个查询可以自行运行,因为我已经通过将值直接放入查询字符串来测试它。我知道这是不好的做法,可以让我接触注射,这就是为什么我不这样做。

我得到的错误如下(为了便于阅读,缩短了堆栈跟踪,但这是唯一的错误,我可以根据请求提供完整的堆栈跟踪):

SEVERE: Servlet.service() for servlet dmat3 threw exception
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: : near line 1, column 118 [SELECT new map(a.id AS id, a.name AS name, a.number AS number ) FROM com.gsipt.dmat3.asset.Asset a ORDER BY :orderBy :orderDirection]
    at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:31)
    at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:24)
    at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:59)
    at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:258)
    at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
    at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
    at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
    at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
    at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
    at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:914)
    at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:1)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
    at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
    at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:912)
    at com.myOrg.myProject.asset.AssetDAO.exampleList(AssetDAO.java:142)
    at com.myOrg.myProject.navigator.NavigatorController.assetGrid(NavigatorController.java:163)

同样,当有单独的参数时,这可以正常工作,但是当它们放在一起时会发生这种情况。可以使用未命名参数重新创建相同的错误,只有“意外令牌”是第二个“?”在查询字符串中。如何将两个名为或未命名的参数放在彼此旁边,这在ORDER BY语句中是有意义的。

谢谢, -Cliff

4 个答案:

答案 0 :(得分:1)

您使用的是find,而不是

findByNamedParams

here。对于Spring 3 API,请参阅here

另请注意,HibernateTemplate文档说

  

注意:从Hibernate 3.0.1开始,   事务性Hibernate访问代码   也可以在普通的Hibernate中编码   样式。因此,对于新开始   项目,考虑采用   标准的Hibernate3编码风格   数据访问对象,而不是基于   SessionFactory.getCurrentSession()。

答案 1 :(得分:1)

您不能在ORDER BY子句中使用参数(命名或位置)。您只能在WHERE子句中使用它们。

答案 2 :(得分:0)

为什么还需要参数化这些?只要orderByorderDirection的值不是来自用户输入,您就可以安全地将值连接到查询中。

if orderDirection == Sort.ASC) {
    queryString += " ASC";
}
else {
    queryString += " DESC";
}

答案 3 :(得分:0)

Params用于指定,而不是用于构建sql语法。只是串起来。