使用Hibernate+HQL查询数据时出现无限循环异常求助
HQL查询Hibernate加载异常分析与解决方案
从你提供的异常栈追踪信息来看,这个问题集中在Hibernate解析并加载实体关联的环节,栈帧出现重复调用,说明加载过程中存在循环或者无法正常解析关联实体的情况。以下是具体的分析和解决思路:
异常栈信息
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:122) at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122) at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86) at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:167) at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4107) at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508) at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478) at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219) at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:278) at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:121) at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89) at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1239) at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1122) at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:680) at org.hibernate.type.EntityType.resolve(EntityType.java:462) at org.hibernate.type.EntityType.resolve(EntityType.java:455) at org.hibernate.type.ComponentType.resolve(ComponentType.java:688) at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.resolveEntityKey(EntityReferenceInitializerImpl.java:142) at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:143) at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:94) at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails$EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:241) at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:122) at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122) at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86) at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:167) at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4107) at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508) at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478) at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219) at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:278) at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:121) at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89) at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1239) at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1122) at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:680) at org.hibernate.type.EntityType.resolve(EntityType.java:462) at org.hibernate.type.EntityType.resolve(EntityType.java:455) at org.hibernate.type.ComponentType.resolve(ComponentType.java:688) at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.resolveEntityKey(EntityReferenceInitializerImpl.java:142) at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.resolveEntityKey(AbstractRowReader.java:143) at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:94) at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails$EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:241) at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:122) at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122) at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86) at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:167) at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4107) at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508)
可能的异常原因
- 实体双向关联形成循环引用:栈中多次重复出现实体加载的调用链,大概率是你的实体类之间存在双向关联(比如
A关联B,B又关联A),且没有配置合理的懒加载策略,导致Hibernate在加载时陷入无限递归。 - 关联实体的主键不存在或类型不匹配:当Hibernate尝试通过主键加载关联实体时,数据库中找不到对应主键的记录,或者实体类的主键类型与数据库表的主键类型不匹配(比如实体用
Integer,数据库是BigInt),导致resolveIdentifier失败。 - Hibernate映射配置错误:组件类型(
ComponentType)的映射存在问题,或者实体关联的mappedBy属性配置错误、关联实体类路径写错,导致无法正确解析关联关系。 - Session/事务状态异常:执行查询时Session被意外关闭,或者事务未正确开启,导致实体加载操作无法正常完成。
对应的解决办法
- 修复循环关联问题:
- 给双向关联的字段添加
fetch = FetchType.LAZY,设置懒加载避免立即加载关联实体;如果需要即时加载但又要避免循环,可以使用@LazyToOne(LazyToOneOption.NO_PROXY)。 - 确认双向关联的
mappedBy属性指向正确,比如在A类的@OneToOne(mappedBy = "a")中,B类的关联字段确实是a。
- 给双向关联的字段添加
- 验证关联实体的主键有效性:
- 检查HQL查询涉及的关联实体主键是否在数据库中存在,比如查询的实体关联了ID为10的另一实体,但数据库中没有该ID的记录。
- 核对实体类主键类型与数据库表主键类型完全一致,避免类型转换错误。
- 修正Hibernate映射配置:
- 检查组件类的字段映射是否正确,确保每个组件字段都对应到正确的数据库列。
- 核对所有关联实体的类路径、关联字段名称,避免拼写错误导致无法找到关联实体。
- 排查Session与事务状态:
- 确保执行HQL查询时Session处于打开状态,事务(如果需要)已经正确开启且未提前提交/回滚。
- 避免在实体加载过程中手动关闭Session,尽量保证Session的生命周期覆盖整个查询操作。
如果能补充对应的HQL语句、实体类的映射代码,我可以帮你更精准地定位问题所在。
内容的提问来源于stack exchange,提问作者bharath
相关产品推荐
相关产品推荐

