Exception in thread "main" org.hibernate.QueryException: illegal attempt to dereference collection

本文介绍了解决Hibernate HQL查询中非法引用集合属性的问题,提供了详细的错误信息及两个有效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在使用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";

保存--->运行--->成功
### Java程序中`IllegalArgumentException: Illegal Capacity: -4`解决方案 遇到`java.lang.IllegalArgumentException: Illegal Capacity: -4`异常通常意味着尝试创建具有负容量的数据结构或设置某个组件的非法大小。此问题可能发生在多种场景下,比如集合类初始化、缓冲区分配或是框架内部资源管理等。 对于该特定错误码 `-4`,表明传入了一个不合法的负数作为参数来指定某种容器或者对象实例化的尺寸。这可能是由于业务逻辑计算失误导致传递给方法调用的实际数值小于零;也有可能是因为配置文件读取不当造成的解析结果不符合预期范围。 #### 可能的原因分析 1. **数据验证不足** 如果应用程序接收外部输入并用于设定某些实体的最大长度或其他形的边界条件,则应确保这些值始终处于合理区间内[^1]。 2. **默认值未正确处理** 当依赖于环境变量或配置项提供初始状态时,如果未能适当地为缺失情况定义合理的回退选项,可能会引起此类异常[^2]。 3. **并发修改引发竞态条件** 多线程环境下共享可变状态可能导致意外行为,特别是在缺乏同步机制的情况下,两个操作几乎同时发生却相互干扰了对方的结果[^3]。 #### 推荐修复措施 为了防止上述情形的发生以及更有效地应对已知问题: - 对所有来自不可信源(如网络请求体、用户界面控件)的数据实施严格的校验流程; - 使用断言语句捕获潜在风险点,在开发阶段尽早暴露患; - 将敏感属性声明成final类型以减少不必要的变更机会; - 增加日志记录功能以便事后追踪定位根本原因。 针对当前案例中的具体表现形——即试图建立一个带有负数容量的对象实例,建议如下调整策略之一: ##### 方案A:增强前置检查 ```java public class Example { public static void main(String[] args){ int capacity = getCapacityFromConfig(); // 获取配置中的capacity if (capacity < 0) { throw new IllegalArgumentException("Invalid negative value for capacity"); } try{ List<Integer> list = new ArrayList<>(capacity); System.out.println("List created successfully with capacity " + capacity); }catch(IllegalArgumentException e){ System.err.println(e.getMessage()); } } private static int getCapacityFromConfig(){ // 模拟从配置获取capacity的过程 return -4; } } ``` 通过引入额外判断分支提前拦截不合规格的情况,可以有效阻止后续代码执行过程中触发类似的运行期错误。 ##### 方案B:修正源头数据 假设问题是源于配置文件或者其他持久化存储介质内的误设,那么应当优先考虑清理脏数据并恢复至正常水平。例如编辑XML文档、JSON字符串或者是数据库表单字段的内容使之满足应用层面对它们的要求。 另外值得注意的是,有时这类异常也可能暗示着其他深层次的设计缺陷,因此除了直接解决问题本身之外,还应该反思整个系统的架构合理性,寻找优化空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值