Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CaseForEqBuilder generates SimpleOperation instead of concrete type #1253

Closed
rt15 opened this issue Mar 12, 2015 · 5 comments
Closed

CaseForEqBuilder generates SimpleOperation instead of concrete type #1253

rt15 opened this issue Mar 12, 2015 · 5 comments
Milestone

Comments

@rt15
Copy link

@rt15 rt15 commented Mar 12, 2015

Hello,

It seems somehow the same issue as:
#702
but applied to CaseForEqBuilder instead of CaseBuilder.

The expression returned by CaseForEqBuilder.Cases.otherwise() comes from a call to abstract method createResult.
There are three implementations of createResult, one that creates a SimpleOperation, another that creates a NumberOperation and the last one that create a StringOperation.
The implementation used depends on which CaseForEqBuilder.then method is used.

But for example, there is no way to obtain a DateExpression, a DateTimeExpression...

Perhaps a solution would be to do somehow like in CaseBuilder.then(Expression expr).
Something like:

    public <T> CaseForEqBuilder<D>.Cases<T, Expression<T>> then(final Expression<T> then)
    {
        type = then.getType();
        return this.inner.new Cases<T, Expression<T>>()
        {
            @SuppressWarnings("unchecked")
            @Override
            protected Expression<T> createResult(Class<T> type, Expression<T> last)
            {
                if (then instanceof StringExpression)
                {
                    return (Expression<T>) StringOperation.create(Ops.CASE_EQ, base, last);
                }
                else if (then instanceof NumberExpression)
                {
                    return (Expression<T>) NumberOperation.create(type, base, last);
                }
                else if (then instanceof DateExpression)
                {
                    return (Expression<T>) DateOperation.create(type, Ops.CASE_EQ, base, last);
                }
                else if (then instanceof DateTimeExpression)
                {
                    return (Expression<T>) DateTimeOperation.create(type, Ops.CASE_EQ, base, last);
                }
                else
                {
                    return SimpleOperation.create(type, Ops.CASE_EQ, base, last);
                }
            }
        }.when(this.other).then(then);
    }

What do you think about that?

@johnjaylward
Copy link

@johnjaylward johnjaylward commented May 27, 2015

I just recently tried upgrading my QueryDSL version from 3.4.1 to 3.6.3 and I am seeing this issue as part of the update. When I try to use the following code, I get an exception about an unknown String Constant:

QVendorSubAccount qva = new QVendorSubAccount("qva");
OrderSpecifier<Long> ord = qva.when(current.getMySubAccount())
    .then(Long.valueOf(0))
    .otherwise(Long.valueOf(1)).asc();
// execute query ordered by ord

This produces an exception:

Stack Trace: 
java.lang.IllegalArgumentException: Unsupported constant VendorSubAccount(id:name)
    at com.mysema.query.jpa.JPQLSerializer.visitLiteral(JPQLSerializer.java:334)
    at com.mysema.query.jpa.JPQLSerializer.visitConstant(JPQLSerializer.java:298)
    at com.mysema.query.support.SerializerBase.visit(SerializerBase.java:201)
    at com.mysema.query.support.SerializerBase.visit(SerializerBase.java:32)
    at com.mysema.query.types.ConstantImpl.accept(ConstantImpl.java:127)
    at com.mysema.query.support.SerializerBase.handle(SerializerBase.java:98)
    at com.mysema.query.support.SerializerBase.visitOperation(SerializerBase.java:281)
    at com.mysema.query.jpa.JPQLSerializer.visitOperation(JPQLSerializer.java:443)
    at com.mysema.query.support.SerializerBase.visit(SerializerBase.java:242)
    at com.mysema.query.support.SerializerBase.visit(SerializerBase.java:32)
    at com.mysema.query.types.OperationImpl.accept(OperationImpl.java:88)
    at com.mysema.query.support.SerializerBase.handle(SerializerBase.java:98)
    at com.mysema.query.support.SerializerBase.visitOperation(SerializerBase.java:278)
    at com.mysema.query.jpa.JPQLSerializer.visitOperation(JPQLSerializer.java:443)
    at com.mysema.query.support.SerializerBase.visit(SerializerBase.java:242)
    at com.mysema.query.support.SerializerBase.visit(SerializerBase.java:32)
    at com.mysema.query.types.OperationImpl.accept(OperationImpl.java:88)
    at com.mysema.query.support.SerializerBase.handle(SerializerBase.java:98)
    at com.mysema.query.jpa.JPQLSerializer.serialize(JPQLSerializer.java:231)
    at com.mysema.query.jpa.JPAQueryBase.serialize(JPAQueryBase.java:57)
    at com.mysema.query.jpa.hibernate.AbstractHibernateQuery.createQuery(AbstractHibernateQuery.java:127)
    at com.mysema.query.jpa.hibernate.AbstractHibernateQuery.createQuery(AbstractHibernateQuery.java:97)
    at com.mysema.query.jpa.hibernate.AbstractHibernateQuery.list(AbstractHibernateQuery.java:223)
... exception trace into my code

"VendorSubAccount(id:name)" is the toString() of my VendorSubAccount class. It appears to be casting my Entity to a String.

After changing to use the simple Id (of type Long) this code works with no errors:

QVendorSubAccount qva = new QVendorSubAccount("qva");
OrderSpecifier<Long> ord = qva.id.when(current.getMySubAccount().getId())
    .then(Long.valueOf(0))
    .otherwise(Long.valueOf(1)).asc();
// execute query ordered by ord
@johnjaylward
Copy link

@johnjaylward johnjaylward commented May 28, 2015

I've confirmed that this only affects the 3.6.x branch. 3.4.1 through 3.5.1 work fine.

@timowest
Copy link
Member

@timowest timowest commented Aug 5, 2015

@johnjaylward Could you try again with 3.6.6?

@johnjaylward
Copy link

@johnjaylward johnjaylward commented Aug 12, 2015

it appears to be working with 3.6.6

@johnjaylward
Copy link

@johnjaylward johnjaylward commented Aug 12, 2015

To clarify, I know this fixed my issue with the case statement in the orderby clause. I'm unsure if it solved the original issue @rt15 posted. They look similar enough that I'd assume that one would be fixed as well.

@timowest timowest removed the progress label Aug 31, 2015
@timowest timowest added this to the 4.0.4 milestone Aug 31, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.