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

Spring Boot 3.3.3迁移后出现Hibernate ModelPart空指针异常

Spring Boot 2.6.5迁移至3.x后Hibernate启动NPE问题

问题背景

将应用从Spring Boot 2.6.5迁移到3.3.3版本,通过OpenRewrite完成迁移后,本地启动时抛出NullPointerException,提示无法调用org.hibernate.metamodel.mapping.ModelPart.getNavigableRole(),因为subPart为null。排查时曾收到映射异常,称com.foo.mysvc.customerdata.model.CustomerAccount实体不存在id属性,尝试将主键字段custAccId改为id后问题依旧。

错误日志

:: Spring Boot ::                (v3.3.3)

2024-09-04 02:03:48 [main] INFO  com.foo.mysvc.Application - Starting Application using Java 17.0.6 with PID 91321 (/Users/johndoe/Projects/Marketplace/mysvc/target/classes started by johndoe in /Users/johndoe/Projects/Marketplace/mysvc)
2024-09-04 02:03:48 [main] DEBUG com.foo.mysvc.Application - Running with Spring Boot v3.3.3, Spring v6.1.12
2024-09-04 02:03:48 [main] INFO  com.foo.mysvc.Application - No active profile set, falling back to 1 default profile: "default"
2024-09-04 02:03:49 [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-09-04 02:03:49 [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 268 ms. Found 18 JPA repository interfaces.
2024-09-04 02:03:50 [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port 8080 (http)
2024-09-04 02:03:50 [main] INFO  o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
2024-09-04 02:03:50 [main] INFO  o.a.catalina.core.StandardService - Starting service [Tomcat]
2024-09-04 02:03:50 [main] INFO  o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.28]
2024-09-04 02:03:50 [main] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2024-09-04 02:03:50 [main] INFO  o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 2083 ms
2024-09-04 02:03:50 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2024-09-04 02:03:51 [main] INFO  com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:mydb user=SA
2024-09-04 02:03:51 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2024-09-04 02:03:51 [main] INFO  o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2024-09-04 02:03:51 [main] INFO  org.hibernate.Version - HHH000412: Hibernate ORM core version 6.5.2.Final
2024-09-04 02:03:51 [main] INFO  o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
2024-09-04 02:03:51 [main] INFO  o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
2024-09-04 02:03:53 [main] INFO  o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2024-09-04 02:03:53 [main] ERROR o.s.o.j.LocalContainerEntityManagerFactoryBean - Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.ModelPart.getNavigableRole()" because "subPart" is null
2024-09-04 02:03:53 [main] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.ModelPart.getNavigableRole()" because "subPart" is null
2024-09-04 02:03:53 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2024-09-04 02:03:53 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2024-09-04 02:03:53 [main] INFO  o.a.catalina.core.StandardService - Stopping service [Tomcat]
2024-09-04 02:03:53 [main] INFO  o.s.b.a.l.ConditionEvaluationReportLogger - 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-09-04 02:03:53 [main] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.ModelPart.getNavigableRole()" because "subPart" is null
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1806)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:954)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
    at com.foo.mysvc.Application.main(Application.java:19)
Caused by: jakarta.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.ModelPart.getNavigableRole()" because "subPart" is null
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1802)
    ... 15 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.ModelPart.getNavigableRole()" because "subPart" is null
    at org.hibernate.boot.query.SqlResultSetMappingDescriptor$AttributeFetchDescriptor.resolve(SqlResultSetMappingDescriptor.java:373)
    at org.hibernate.boot.query.SqlResultSetMappingDescriptor$EntityResultDescriptor.lambda$resolve$0(SqlResultSetMappingDescriptor.java:264)
    at java.base/java.util.HashMap.forEach(HashMap.java:1421)
    at org.hibernate.boot.query.SqlResultSetMappingDescriptor$EntityResultDescriptor.resolve(SqlResultSetMappingDescriptor.java:261)
    at org.hibernate.boot.query.SqlResultSetMappingDescriptor.lambda$resolve$0(SqlResultSetMappingDescriptor.java:123)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.hibernate.boot.query.SqlResultSetMappingDescriptor.resolve(SqlResultSetMappingDescriptor.java:122)
    at org.hibernate.query.internal.NamedObjectRepositoryImpl.lambda$prepare$3(NamedObjectRepositoryImpl.java:199)
    at java.base/java.util.HashMap$Values.forEach(HashMap.java:1065)
    at org.hibernate.boot.internal.MetadataImpl.visitNamedResultSetMappingDefinition(MetadataImpl.java:279)
    at org.hibernate.query.internal.NamedObjectRepositoryImpl.prepare(NamedObjectRepositoryImpl.java:197)
    at org.hibernate.boot.internal.SessionFactoryObserverForNamedQueryValidation.sessionFactoryCreated(SessionFactoryObserverForNamedQueryValidation.java:37)
    at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:322)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:457)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1506)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
    ... 19 common frames omitted

实体类代码

package com.foo.mysvc.customerdata.model;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import jakarta.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name="CUSTOMER_ACCOUNT")
@Data
public class CustomerAccount {

    @Id
    @Column(name="CUST_ACC_ID")
    private String custAccId; //pk

    @Column(name = "CUSTOMER_INFO_ID")
    private Long customerInfoId;

    @ToString.Exclude
    @EqualsAndHashCode.Exclude
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CUSTOMER_INFO_ID", referencedColumnName = "id", insertable=false, updatable=false)
    private CustomerInfo customerInfo; //fk

    @Column(name="INTERNAL_ACC_NUMBER")
    private String internalAccNumber;

    @Column(name="MASKED_NUMBER")
    private String maskedNumber;

    @Column(name="PRODUCT_DESCRIPTION")
    private String productDesc;

    @Column(name="ACC_TYPE")
    private String accountType;

    @Column(name="BASE_CCY")
    private String baseCurrency;

    @Column(name="ACTIVE")
    private boolean active;

    @CreationTimestamp
    private LocalDateTime createdAt;

    @UpdateTimestamp
    private LocalDateTime updatedAt;
}

解决方案

从错误栈分析,问题和实体类主键无关——你的实体主键配置完全合法,改名为id属于无效操作。核心原因是Hibernate启动时验证**SQL结果集映射(SqlResultSetMapping)**时,发现了无效的属性引用,导致解析过程中抛出空指针。

具体排查和修复步骤:

  1. 全局搜索项目中的@SqlResultSetMapping和@NamedNativeQuery

    • 检查所有结果集映射配置,核对@FieldResult、@ColumnResult中指定的属性名是否和实体类实际字段完全匹配,注意大小写和拼写。
    • 重点排查涉及CustomerAccount或关联实体CustomerInfo的映射配置,看是否存在引用不存在属性的情况。
  2. 检查OpenRewrite迁移后的注解变更

    • 迁移过程中工具会将javax.persistence替换为jakarta.persistence,但可能遗漏部分配置。确认所有JPA相关注解的包路径正确,特别是原生查询和结果集映射的注解。
  3. 验证关联实体CustomerInfo的配置

    • 确认CustomerInfo实体的主键id存在且标注@Id注解,检查是否有结果集映射错误引用了该实体的属性。
  4. 临时绕过验证(仅用于排查)

    • 如果暂时无法定位问题,可添加以下配置关闭Hibernate的命名查询验证,先让应用启动再逐步排查:
      hibernate.session_factory.observers.enabled=false
      
      此配置仅作为临时方案,最终必须修复无效的结果集映射配置。

总结

该错误的根源是无效的SqlResultSetMapping配置,和实体主键无关。通过排查所有结果集映射和原生查询的属性引用,即可解决启动时的空指针问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:32:02