You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JPA Repository含Bs1100Not方法启动报StackOverflowError,本地正常

问题分析与解决

问题场景

Repository定义:

@Repository
public interface BooksForHealthPolicyRepository extends JpaRepository<BooksForHealthPolicy, BooksForHealthPolicyId>{

    public List<BooksForHealthPolicy> findByCollectionDateGreaterThanEqualAndCollectionDateLessThanEqualAndProductCodeAndProductSubCodeAndBs1100Not(int collectionStartDate,int collectionEndDate, int productCode, int productSubCode,char bs1100);
}

实体类对应字段:

@Column(name = "BS1100", nullable = false, length = 1)
private char bs1100;

服务启动时抛出错误:

Exception: java.lang.StackOverflowError org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:116) org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:120) org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:120) org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:120) org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:120) org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:120) org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:120) org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:120) org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:120) org.hibernate.hql.internal.ast.util.JoinProcessor.doFindAllNodes(JoinProcessor.java:120) 

本地运行正常,部署后启动失败,怀疑和Not关键字有关。

原因分析

  • 依赖版本差异:本地与部署环境的Hibernate/Spring Data JPA版本不一致,旧版本在解析Not关键字搭配char类型字段时,存在递归解析的bug,触发栈溢出。
  • char类型兼容性问题:JPA对基本类型char的解析支持不如包装类型Character,加上Not关键字后,HQL解析器陷入无限递归逻辑。

解决方法

方法一:替换Not为标准写法IsNot

Spring Data JPA的查询命名规范中,IsNot是更稳定的否定写法,部分旧版本Hibernate对该写法的解析逻辑更完善:

List<BooksForHealthPolicy> findByCollectionDateGreaterThanEqualAndCollectionDateLessThanEqualAndProductCodeAndProductSubCodeAndBs1100IsNot(int collectionStartDate, int collectionEndDate, int productCode, int productSubCode, char bs1100);

方法二:用@Query手写HQL绕开自动解析

直接编写查询语句,避免方法名自动解析的问题:

@Query("SELECT b FROM BooksForHealthPolicy b WHERE b.collectionDate >= :start AND b.collectionDate <= :end AND b.productCode = :code AND b.productSubCode = :subCode AND b.bs1100 != :bs1100")
List<BooksForHealthPolicy> findFilteredBooks(
    @Param("start") int collectionStartDate,
    @Param("end") int collectionEndDate,
    @Param("code") int productCode,
    @Param("subCode") int productSubCode,
    @Param("bs1100") char bs1100);

方法三:将实体类字段改为Character包装类型

把基本类型char换成包装类型,提升JPA解析的兼容性:

@Column(name = "BS1100", nullable = false, length = 1)
private Character bs1100;

同时更新Repository方法的参数类型为Character。

方法四:统一本地与部署环境的依赖版本

检查Maven的pom.xml或Gradle的build.gradle,确保部署环境的Spring Data JPA、Hibernate版本和本地完全一致,消除版本差异带来的解析bug。


内容的提问来源于stack exchange,提问作者msadasjwd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:30:57