Как создать выражение с постоянным числовым значением в QueryDSL?

#java #jpa-2.0 #querydsl

#java #jpa-2.0 #querydsl

Вопрос:

Я бы хотел создать подобный запрос с помощью QueryDSL

 update WorkMessage w set w.totalPrice = 0.12 - w.totalCost;
  

Я пробовал так

     Expression<Float> priceExpr = Expressions.constant(0.12f);

    new JPAUpdateClause(em, w)
            .set(w.totalPrice , priceExpr.subtract(w.totalCost));
  

Но это не работает — выражение не имеет метода вычитания.

Я сделал это так:

         new JPAUpdateClause(em, w)
            .set(w.totalPrice , w.totalCost.subtract(0.12f).negate());
  

но я хотел бы знать, как это сделать первым способом.

//Редактировать

Второй способ не работает:

JPAUpdateClause.toString говорит:

 update WorkMessage workMessage 
set workMessage.totalPrice = -(workMessage.totalCost - :a1)
  

но результат SQL

 update work_message set total_price=-total_cost-?
  

Круглые скобки просто исчезли. Я делаю что-то не так? Это выглядит следующим образом:

 w.totalCost.subtract(0.12f).negate()
w.totalCost.negate().subtract(0.12f)
  

получите тот же результат.

Для вышеупомянутой проблемы

 w.totalCost.negate().add(0.12f)
  

работает. Но я думаю, что есть ошибка.

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

1. Не могли бы вы открыть для него заявку на GitHub: github.com/mysema/querydsl/issues

2. QueryDSL работает нормально. Это ошибка гибернации. обновление WorkMessage workMessage set workMessage.earnedPrice = — ( workMessage.TotalCost — :a1 ) преобразуется в обновление work_message set earned_price=-total_cost-?

3. Я думал, что это что-то с QueryDSL, но это связано с самим спящим режимом. Возникла проблема hibernate.onjira.com/browse/HHH-6714 . Спасибо за помощь.

Ответ №1:

Некоторое время назад мы удалили типы констант DSL из Querydsl. Если вы действительно хотите написать это первым способом, тогда вы должны выразить это следующим образом :

 Expressions.operation(Float.class, Ops.SUB, 
    Expressions.constant(0.12f), w.totalCost)
  

или

 NumberOperation.create(Float.class, Ops.SUB, 
    Expressions.constant(0.12f), w.totalCost)
  

если вам нужно числовое выражение

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

1. Спасибо, Тимо. Не могли бы вы посмотреть на //Edit часть выше?

2. В чем причина отсутствия постоянных числовых выражений? Мне действительно нужно NumberExpression<Целое число> с нулевым значением сейчас.

3. Причинами были ненужная сложность API и накладные расходы на обслуживание. NumberTemplate. НОЛЬ должен работать для вас.

Ответ №2:

Некоторое время назад у меня была такая же проблема (нужна была константа 0), и я создал свой собственный класс ConstantNumberExpression . Это оказалось на удивление просто 🙂

У коллеги только что была такая же проблема с константой 1, поэтому я решил опубликовать ее здесь.

 private static class ConstantNumberExpression extends NumberExpression<Integer> {
    private static final long serialVersionUID = 1220768215234001828L;

    public ConstantNumberExpression(final int constant) {
        super(new ConstantImpl<>(constant));
    }

    @Override
    @Nullable
    public <R, C> R accept(final Visitor<R, C> v, @Nullable final C context) {
        return v.visit((Constant<Integer>) mixin, context);
    }
}
  

Конечно, это можно было бы сделать немного более обобщенно, используя параметр типа, но нам это было нужно только для целого числа (на самом деле только для нуля и единицы).

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

1. В этом случае вы можете использовать com.mysema. запрос.типы. Константа или ConstantImpl