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

Error with subtype association join using querydsl integration #1944

Open
azizairo opened this issue Oct 24, 2024 · 6 comments
Open

Error with subtype association join using querydsl integration #1944

azizairo opened this issue Oct 24, 2024 · 6 comments

Comments

@azizairo
Copy link

azizairo commented Oct 24, 2024

Hi, I am getting the error: Attribute not found while trying to join subtype associations.
Here is my query:

blazeJPAQueryFactory.with(maxLessonContentVersionCTE, subquery1)
        .select(moduleUnit)
        .from(moduleUnit)
        .leftJoin(moduleUnit.as(QLesson.class).contents, lessonContent).fetchJoin()
        .fetchOne();

If i use querydsl without blazepersistance, this query will work

@jwgmeligmeyling
Copy link
Collaborator

I am not familiar with the .as(QClass) syntax, but contrary to HQL/JPQL, in JPQLNext I believe sub-type attributes are not present on the parent type. Instead the expression needs to be explicitly treated:

JPQLNextExpressions.treat(moduleUnit, QLesson.class)

Would be the syntax for that I guess

@azizairo
Copy link
Author

azizairo commented Oct 24, 2024

As I understood from method treat, method does not give us possibility to treat parent classes as their subtypes

public static <T> Expression<T> treat(Class<T> result, Expression<?> expression) {
        if (Boolean.class.equals(result) || boolean.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_BOOLEAN, expression);
        } else if (Byte.class.equals(result) || byte.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_BYTE, expression);
        } else if (Short.class.equals(result) || short.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_SHORT, expression);
        } else if (Long.class.equals(result) || long.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_LONG, expression);
        } else if (Integer.class.equals(result) || int.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_INTEGER, expression);
        } else if (Float.class.equals(result) || float.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_FLOAT, expression);
        } else if (Double.class.equals(result) || double.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_DOUBLE, expression);
        } else if (Character.class.equals(result) || char.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_CHARACTER, expression);
        } else if (String.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_STRING, expression);
        } else if (BigInteger.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_BIGINTEGER, expression);
        } else if (BigDecimal.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_BIGDECIMAL, expression);
        } else if (Calendar.class.equals(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_CALENDAR, expression);
        } else if (Timestamp.class.isAssignableFrom(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_TIMESTAMP, expression);
        } else if (Time.class.isAssignableFrom(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_TIME, expression);
        } else if (Date.class.isAssignableFrom(result)) {
            return Expressions.simpleOperation(result, JPQLNextOps.TREAT_DATE, expression);
        } else {
            throw new IllegalArgumentException("No cast operation for " + result.getName());
        }
    }

.as(QClass) casts the path to a subtype querytype, so with it i can join subtype association. But it does not work with BlazePersistance

@jwgmeligmeyling
Copy link
Collaborator

Treat should do precisely that, although I apparently mixed up the parameters:

JPQLNextExpressions.treat(QLesson.class, moduleUnit) should complile and return a QLesson instance (which has the contents) field.

@jwgmeligmeyling
Copy link
Collaborator

The issue with moduleUnit.as(QLesson.class) is that it doesn't actually render the cast in the query but rather just relies on subTypeField being present in the ParentEntity anyway. This behaviour is however Hibernate specific (or maybe JPA?) and Blaze-Persist decided to require explicit treat operations.

@azizairo
Copy link
Author

JPQLNextExpressions.treat() method returns Expression type and it can not be cast to QLesson classes.

public static <T> Expression<T> treat(Class<T> result, Expression<?> expression) {...}

@azizairo
Copy link
Author

I found the correct treat method that can cast parents to the specified subtype. Thank a lot!
P.S.: The correct method was in JPAExpressions.class

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants