今天在使用HQL查询时一直报错:
Exception in thread "main" org.hibernate.QueryException: illegal attempt to dereference collection [person0_.person_id.myEvent] with element property reference [title] [from com.mao.Person p where p.myEvent.title > :title]
at org.hibernate.QueryException.generateQueryException(QueryException.java:137)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:120)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:234)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93)
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:1836)
at com.mao.join.HqlQuery.findPersons(HqlQuery.java:31)
at com.mao.join.HqlQuery.main(HqlQuery.java:17)
Caused by: org.hibernate.QueryException: illegal attempt to dereference collection [person0_.person_id.myEvent] with element property reference [title]
at org.hibernate.hql.internal.ast.tree.DotNode$1.buildIllegalCollectionDereferenceException(DotNode.java:73)
at org.hibernate.hql.internal.ast.tree.DotNode.checkLhsIsNotCollection(DotNode.java:618)
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:252)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:126)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:121)
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:959)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1267)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4686)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:4228)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2104)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:796)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:597)
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)
... 9 more
相关HQL部分代码:
List pl = sess.createQuery("from Person p where p.myEvent.title > :title")
// 执行setString()方法为HQL语句的参数赋值
.setString("title", " ")
//Query调用list()方法访问查询的全部实例
.list();
报错原因:
在Hibernate3.2.3以前的版本中对所有的关联实体自动使用隐式连接。对于以下HQL语句:
List pl = sess.createQuery("from Person p where p.myEvent.title > :title")
无论如何Hibernate都会对p.myEvent.title自动使用隐式连接,所以以上HQL语句总是有效。
但是Hibernate3.2.2版本以后,Hibernate改变了默认的隐式策略,改为:(以上面的HQL语句为例)
1:如果myEvent是普通组件属性,或者单个的关联实体,则Hibernate会自动生成隐式内连接,也就是上面的HQL语句依然有效。
2:如果myEvent是一个集合,包括1—N、N-1关联,那么系统就会抛出
Exception in thread "main" org.hibernate.QueryException: illegal attempt to dereference collection异常
解决方案:
1:退回使用Hibernate3.2.3版本(当然不太推荐)
2:改为显示连接。
以上面的HQL为例改为:
String hql="from Person p inner join p.myEvent e where e.title > :title";
保存--->运行--->成功