Invalid query generated for Element Collection in Embeddable

Bug #823782 reported by Paul Nardone
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Querydsl
Fix Released
Undecided
Unassigned

Bug Description

Attempting to implement a query

SELECT x FROM BookVersion x JOIN x.definition.bookMarks bm WHERE size(x.definition.bookMarks) = :sz AND (bm.page = 2357 OR bm.page = 2356)

in Query DSL

 QBookVersion bookVersion = QBookVersion.bookVersion;
        JPQLQuery query = new JPAQuery(entityManager);

        List<BookVersion> bob = query.from(bookVersion)
          .where(bookVersion.definition.bookMarks.size().eq(1)
                  .and(bookVersion.definition.bookMarks.any().page.eq(2356L)
                          .or(bookVersion.definition.bookMarks.any().page.eq(2357L))))
          .list(bookVersion);

Results in error where JQL generated assumes BookMark is an mapped entity

java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException: BookMark is not mapped [select bookVersion
from test.BookVersion bookVersion
where size(bookVersion.definition.bookMarks) = :a1 and (exists (select 1
from BookMark bookVersion_definition_bookMarks
where bookVersion_definition_bookMarks in elements(bookVersion.definition.bookMarks) and bookVersion_definition_bookMarks.page = :a2) or exists (select 1
from BookMark bookVersion_definition_bookMarks
where bookVersion_definition_bookMarks in elements(bookVersion.definition.bookMarks) and bookVersion_definition_bookMarks.page = :a3))]
 at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1202)
 at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148)
 at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:275)
 at com.mysema.query.jpa.impl.DefaultSessionHolder.createQuery(DefaultSessionHolder.java:27)
 at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:121)
 at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:90)
 at com.mysema.query.jpa.impl.AbstractJPAQuery.list(AbstractJPAQuery.java:244)
 at test.Test.testTestSystem(Test.java:122)
 at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:60)
 at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:106)
 at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
 at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
 at $Proxy0.invoke(Unknown Source)
 at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
 at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
 at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
Caused by: org.hibernate.hql.ast.QuerySyntaxException: BookMark is not mapped [select bookVersion
from test.BookVersion bookVersion
where size(bookVersion.definition.bookMarks) = :a1 and (exists (select 1
from BookMark bookVersion_definition_bookMarks
where bookVersion_definition_bookMarks in elements(bookVersion.definition.bookMarks) and bookVersion_definition_bookMarks.page = :a2) or exists (select 1
from BookMark bookVersion_definition_bookMarks
where bookVersion_definition_bookMarks in elements(bookVersion.definition.bookMarks) and bookVersion_definition_bookMarks.page = :a3))]
 at org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:180)
 at org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:111)
 at org.hibernate.hql.ast.tree.FromClause.addFromElement(FromClause.java:93)
 at org.hibernate.hql.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:327)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3441)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3325)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:733)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:584)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.collectionFunctionOrSubselect(HqlSqlBaseWalker.java:4696)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:4390)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2047)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1997)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1975)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:831)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:617)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:244)
 at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:254)
 at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:185)
 at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
 at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
 at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
 at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124)
 at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
 at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
 at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1770)
 at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:272)
 ... 39 more

Revision history for this message
Paul Nardone (paul-nardone) wrote :
Revision history for this message
Timo Westkämper (timo-westkamper) wrote :

Are you able to execute this in JPQL/HQL?

I tried this :

QBookVersion bookVersion = QBookVersion.bookVersion;
QBookMark bookMark = new QBookMark(PathMetadataFactory.forVariable("bookMark"));

query().from(bookVersion)
    .innerJoin(bookVersion.definition.bookMarks, bookMark)
    .where(
        bookVersion.definition.bookMarks.size().eq(1),
        bookMark.page.eq(2357L).or(bookMark.page.eq(2356L)))
    .list(bookVersion);

and got an Exception as well

Revision history for this message
Paul Nardone (paul-nardone) wrote :

Yes the query below is in the same test above the QueryDSL version and that executes fine

SELECT x FROM BookVersion x JOIN x.definition.bookMarks bm WHERE size(x.definition.bookMarks) = :sz AND (bm.page = 2357 OR bm.page = 2356)

The reason I looked at QueryDSL was the Hibernate implentation of JPA Criteria API doesn't seem to be able to handle it either https://hibernate.onjira.com/browse/HHH-6562

Revision history for this message
Timo Westkämper (timo-westkamper) wrote :

The query I gave worked after all, I just forgot to add the new entity classes to the Hibernate configuration.

I will make sure that default variables embeddable types are created.

Revision history for this message
Timo Westkämper (timo-westkamper) wrote :

Here is a related ticket for the embeddable default variables : https://bugs.launchpad.net/querydsl/+bug/824334

Revision history for this message
Timo Westkämper (timo-westkamper) wrote :

Could you confirm that your query works now?

Changed in querydsl:
status: New → Fix Committed
Revision history for this message
Timo Westkämper (timo-westkamper) wrote :

Fixed in 2.2.2

Changed in querydsl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.