Ошибка второй замены именованного параметра в HQL

#java #hibernate #hql

#java #переход в спящий режим #hql

Вопрос:

У меня есть оператор HQL такого рода:

 update versioned MyTable t 
set t.myCol = case 
   when ((t.myCol   :myColChange) < 0) then 0 
   else (t.myCol   :myColChange) end
  

Я вижу, что это не работает из-за второго появления :myColChange . Выдается следующее исключение:

org.hibernate.Исключение QueryException: не все именованные параметры были установлены: [myColChange] [ обновление версии MyTable t устанавливает t.myCol = случай, когда ((t.myCol :myColChange) < 0) затем 0 еще (t.myCol : myColChange) заканчивается]

Был бы признателен за любые идеи по решению этой проблемы. Спасибо!

Комментарии:

1. Как насчет публикации кода, который создает запрос и задает значения параметра? 😉

Ответ №1:

Как насчет

 .... set t.myCol = max(0, t.myCol   :myColChange)
  

Комментарии:

1. Спасибо, это была хорошая идея. Но его скорее установить t.myCol = greatest(0, т.myCol :myColChange) Однако это тоже вызывает то же исключение. Таким образом, проблема не могла быть связана со вторым появлением параметра. Есть идеи, почему это происходит?

Ответ №2:

Обходным путем было бы использовать два разных имени / параметра.

 update versioned MyTable t 
set t.myCol = case 
   when ((t.myCol   :myColChange1) < 0) then 0 
   else (t.myCol   :myColChange2) end
  

Ответ №3:

Вы на самом деле

 setXXXXX("myColChange", myColChangeValue);
  

на объекте запроса перед его выполнением?

Я просто спрашиваю, потому что вы не опубликовали свой код.

Комментарии:

1. Да, я сделал. И я мог видеть значение во время отладки. Я не публикую код, потому что мы вызываем код архитектуры, специфичный для нашей компании, чтобы получить его, и было бы бессмысленно публиковать его здесь.

Ответ №4:

У меня тоже эта проблема. Мой текущий обходной путь заключается не в использовании именованных параметров, а в использовании позиций вместо них.

Для меня это не большая проблема, потому что я сохраняю параметры запроса в моем собственном объекте в виде списка.

     public void apply( final CategoryFilter f )
    {
        final String jsonFilter = f.getFilter();
        final QueryParameters queryParams = QueryParameters.createFromJsonString( jsonFilter );

        final StringBuilder queryStringBuilder =
            new StringBuilder( "UPDATE Transaction t SET t.category = 'myCatergory' WHERE " );

        boolean isFirst = true;
        for ( final QueryParameter queryParam : queryParams.getQueryParams() )
        {
            if (!isFirst)
            {
                queryStringBuilder.append( " AND " );
            }
            else
            {
                isFirst = false;
            }
            queryStringBuilder.append( "t." );
            queryStringBuilder.append( queryParam.getField() );
            queryStringBuilder.append( " " );
            queryStringBuilder.append( queryParam.getOp() );
            queryStringBuilder.append( " ? " );
        }
        final Query q = getSession().createQuery( queryStringBuilder.toString() );

        int index = 0;
        for ( final QueryParameter queryParam : queryParams.getQueryParams() )
        {
            q.setParameter( index  , queryParam.getValue() );
        }
        q.executeUpdate();

    }