I’m using JPA 2.1 and Hibernate 4.3.6.Final. I’m trying to use CriteriaBuilder to write a left outer join with conditions, so I have
final CriteriaBuilder cb = m_entityManager.getCriteriaBuilder();
CriteriaQuery<Message> query = cb.createQuery(Message.class);
Root<Message> messageRoot = query.from(Message.class);
final Join<Message, Group> groupJoin = messageRoot.join(Message_.group);
final Join<Message, MessageReadDate> msgReadDateJoin = messageRoot.join(Message_.messageReads, JoinType.LEFT);
// form left outer join clause.
msgReadDateJoin.on( cb.equal(messageRoot, msgReadDateJoin.get(MessageReadDate_.message)),
cb.equal(msgReadDateJoin.get(MessageReadDate_.recipient), recipient) );
Ultimately, this produces an exception when I run my query, which is below. I don’t understand what the error message means, but more importantly, how do I rewrite my query (above) to achieve the same thing but cure this annoying exception?
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.InvalidWithClauseException: with clause can only reference columns in the driving table [select generatedAlias0 from org.mainco.subco.myrpoject.domain.Message as generatedAlias0 inner join generatedAlias0.group as generatedAlias1 left join generatedAlias1.classroom as generatedAlias2 left join generatedAlias2.roster as generatedAlias3 left join generatedAlias0.messageReads as generatedAlias4 with ( generatedAlias0=generatedAlias4.message ) and ( generatedAlias4.recipient=:param0 ) where ( generatedAlias4.message is null ) and ( generatedAlias3.classroom=generatedAlias0.group.classroom ) and ( generatedAlias1.name=:param1 ) and ( generatedAlias3.user=:param2 ) and ( generatedAlias3.enabled=:param3 )]
at org.hibernate.hql.internal.ast.HqlSqlWalker$WithClauseVisitor.visit(HqlSqlWalker.java:509)
at org.hibernate.hql.internal.ast.util.NodeTraverser.visitDepthFirst(NodeTraverser.java:78)
at org.hibernate.hql.internal.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:67)
at org.hibernate.hql.internal.ast.HqlSqlWalker.handleWithFragment(HqlSqlWalker.java:437)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:414)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3903)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3689)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3567)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:708)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:564)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:126)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:88)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1800)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:568)
at org.hibernate.jpa.criteria.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:336)
at org.hibernate.jpa.criteria.compile.CriteriaCompiler.compile(CriteriaCompiler.java:147)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:736)
at sun.reflect.GeneratedMethodAccessor23.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at com.sun.proxy.$Proxy68.createQuery(Unknown Source)
at org.mainco.subco.myrpoject.repo.MessageDaoImpl.getUnreadClassAnnouncements(MessageDaoImpl.java:168)
at org.mainco.subco.myrpoject.repo.MessageDaoImpl.getUnreadMessages(MessageDaoImpl.java:139)
at org.mainco.subco.myrpoject.repo.MessageDaoIT.testCreateMessage(MessageDaoIT.java:319)
Check https://hibernate.atlassian.net/browse/HHH-2772 , looks like this is a bug in Hibernate. Try to use the primary keys (i.e., the IDs) instead of the object references in the ON clause
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With