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

SpringBoot 2.1.1升级到2.7.5(Java17)触发NPE问题求助

问题:SpringBoot 2.7.5(Java17)启动时JPA原生查询引发NullPointerException

错误信息

Caused by: java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because "variable" is null
at org.springframework.data.jpa.repository.query.QueryUtils.createCountQueryFor(QueryUtils.java:607)
at org.springframework.data.jpa.repository.query.DefaultQueryEnhancer.createCountQueryFor(DefaultQueryEnhancer.java:49)
at org.springframework.data.jpa.repository.query.StringQuery.deriveCountQuery(StringQuery.java:119)
at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.(AbstractStringBasedJpaQuery.java:72)
at org.springframework.data.jpa.repository.query.NativeJpaQuery.(NativeJpaQuery.java:53)
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:51)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:169)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:253)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:93)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:103)
... 60 common frames omitted

当前依赖配置

implementation 'org.springframework.boot:spring-boot:2.7.5'

implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('org.springframework.boot:spring-boot-starter-actuator')
implementation('org.springframework.boot:spring-boot-starter-web')
implementation('org.springframework.boot:spring-boot-starter-parent:2.7.5')

implementation('org.springframework:spring-jdbc')
implementation('org.springframework:spring-orm')
implementation('org.springframework:spring-core')
implementation('org.springframework:spring-beans')
implementation('org.springframework:spring-webmvc')
implementation('org.springframework:spring-web')
implementation('org.springframework:spring-context')
testImplementation 'org.springframework:spring-test:5.3.25'
compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.5'
runtime("org.springframework.boot:spring-boot-properties-migrator")
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
implementation group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '9.0.56'
implementation group: 'org.hibernate', name: 'hibernate-core', version: '5.6.5.Final'
implementation 'org.springframework.cloud:spring-cloud-context:3.1.0'
implementation group: 'org.springframework.security', name: 'spring-security-core', version: '5.6.9'
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
implementation group: 'org.hibernate', name: 'hibernate-entitymanager', version: '5.4.0.Final'
implementation group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-2.1-api', version: '1.0.2.Final'
implementation("net.bytebuddy:byte-buddy:1.14.0")
compileOnly 'org.projectlombok:lombok:1.18.26'
annotationProcessor 'org.projectlombok:lombok:1.18.26'

触发错误的查询代码

@Modifying
@Transactional
@Query(value = "INSERT INTO W (CREATED_DATE, PRODUCT_CODE, TENANT_ID, UPDATED_DATE, UUID, STORE_ID) SELECT TO_TIMESTAMP(:createdDate, :format), :productCode, :tenantId, TO_TIMESTAMP(:updatedDate, :format), :uuid, :storeId FROM W WHERE ROWNUM <= 1 AND NOT EXISTS (select * from W w2 WHERE UUID = :uuid  AND PRODUCT_CODE =:productCode)" ,nativeQuery = true)
int insertIntoW(@Param("format") String format, @Param("createdDate")String createdDate, @Param("productCode")String productCode, @Param("tenantId")String tenantId, @Param("updatedDate") String updatedDate, @Param("uuid")String uuid, @Param("storeId") String storeId);

解决方案

1. 修复JPA查询注解

Spring Data JPA 2.7版本会尝试为带@Modifying的原生查询自动生成count查询,但INSERT语句无查询结果,导致解析时触发NPE。只需在@Query注解中显式指定空的countQuery,阻止自动生成逻辑:

@Modifying
@Transactional
@Query(value = "INSERT INTO W (CREATED_DATE, PRODUCT_CODE, TENANT_ID, UPDATED_DATE, UUID, STORE_ID) SELECT TO_TIMESTAMP(:createdDate, :format), :productCode, :tenantId, TO_TIMESTAMP(:updatedDate, :format), :uuid, :storeId FROM W WHERE ROWNUM <= 1 AND NOT EXISTS (select * from W w2 WHERE UUID = :uuid  AND PRODUCT_CODE =:productCode)", 
       nativeQuery = true, 
       countQuery = "")
int insertIntoW(@Param("format") String format, @Param("createdDate")String createdDate, @Param("productCode")String productCode, @Param("tenantId")String tenantId, @Param("updatedDate") String updatedDate, @Param("uuid")String uuid, @Param("storeId") String storeId);

2. 清理冗余依赖

当前依赖存在重复、冲突和不必要的单独引入,清理后可避免版本兼容性问题:

  • 移除implementation('org.springframework.boot:spring-boot-starter-parent:2.7.5'):parent应在构建脚本的parent区块配置,而非implementation依赖
  • 移除单独引入的spring-core、spring-beans、spring-webmvc等Spring核心依赖:这些已被spring-boot-starter-web、spring-boot-starter-data-jpa自动包含
  • 移除compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.5':保留javax.servlet-api:4.0.1即可,避免版本冲突
  • 移除hibernate-entitymanager、hibernate-jpa-2.1-api:hibernate-core:5.6.5.Final已包含这些功能,且Spring Boot starter已引入正确的JPA API

清理后的依赖示例:

plugins {
    id 'org.springframework.boot' version '2.7.5'
    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.cloud:spring-cloud-context:3.1.0'
    implementation 'org.springframework.security:spring-security-core:5.6.9'
    implementation 'javax.xml.bind:jaxb-api:2.3.1'
    implementation 'net.bytebuddy:byte-buddy:1.14.0'
    compileOnly 'org.projectlombok:lombok:1.18.26'
    annotationProcessor 'org.projectlombok:lombok:1.18.26'
    runtime("org.springframework.boot:spring-boot-properties-migrator")
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
    useJUnitPlatform()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:22:05