Непрерывные проблемы именованных параметров в Hibernate (Spring HibernateTemplate) - PullRequest
3 голосов
/ 01 июля 2011

Я пытаюсь использовать именованные параметры для вставки некоторых строк в запрос.Я использую 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 ]

1 голос
/ 01 июля 2011

Нельзя использовать параметры (именованные или позиционные) в предложении ORDER BY.Вы можете использовать их только в предложении WHERE.

1 голос
/ 01 июля 2011

Вы используете find, а не

findByNamedParams

См. здесь .Для API Spring 3 см. здесь .

Также обратите внимание, что в документации HibernateTemplate написано

ПРИМЕЧАНИЕ. Начиная с Hibernate 3.0.1, транзакционный код доступа Hibernateтакже может быть закодирован в простом стиле Hibernate.Следовательно, для недавно начатых проектов рассмотрите возможность принятия вместо этого стандартного стиля Hibernate3 для кодирования объектов доступа к данным на основе SessionFactory.getCurrentSession ().

0 голосов
/ 01 июля 2011

Параметры предназначены для указания значений , а не для создания синтаксиса sql. Просто конкатанируйте струны.

0 голосов
/ 01 июля 2011

Почему вы все равно должны их параметризовать?Пока значения orderBy и orderDirection не поступают из пользовательского ввода, вы можете просто объединить значения в запрос.

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

и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...