Invalid query generated for Element Collection in Embeddable

Bug #823782 reported by Paul Nardone on 2011-08-10
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

Paul Nardone (paul-nardone) 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

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

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.

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

Could you confirm that your query works now?

Changed in querydsl:
status: New → Fix Committed

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  Edit
Everyone can see this information.

Other bug subscribers

Bug attachments