How to Create Constant Numeric Value Expression in Querydsl?

How to Create Constant Numeric Value Expression in Querydsl?

I'd like to create query like this with QueryDSL

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

I tried like this

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

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

But this doesn't work - Expression doesn't have subtract method.

I did it like this:

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

but I'd like to know how to do it the first way.

//EDit

The second way don't work:

JPAUpdateClause.toString says:

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

but the SQL result is

update work_message set total_price=-total_cost-?

Parentheses just dissapeared. Am I doing something wrong? It looks like theese:

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

have the same result.

For the above problem

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

works. But I think there is a bug.

3

2 Answers

We removed the DSL Constant types some time ago from Querydsl. If you really want to write it the first way, then you have to express it like this :

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

or

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

if you need a NumberExpression

3

I had the same problem some time ago (needed the constant 0), and did build my own ConstantNumberExpression class. It turned out surprisingly easy :-)

A collegue just had the same problem, for the constant 1, so I decided to post it here.

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

Of course this could be done a bit more generic, using a type parameter, but we did need it only for Integer (actually only for zero and one).

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Chloe Bennett
Author

Chloe Bennett

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.