spring-boothibernatespring-data-jpahibernate-mapping

Getting Cannot invoke "org.hibernate.metamodel.mapping.ModelPart.getNavigableRole()" because "subPart" is null after migrating to Spring Boot 3.3.3


I have a task to migrate to Spring Boot 3.x (from Spring Boot 2.6.5) and I chose OpenRewrite tool to help me with this task. After all the migration changes were done, running the application locally gives me the error below.

 :: 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

Upon searching stackoverflow regarding this issue I found below issues which I used as reference

Same issue with no fix Getting property [djob] not found on entity [com.xxx.JobsDeviceIds] after upgrading to Spring framework 3.2.2

Same issue with no fix Problem with Composite Primary Keys in JPA (Migrating from hibernate-jpa 2.1 to jakarta-persistence 3.1.0)

Almost similar issue but fix doesn't apply to my scenario Spring 3 with Hibernate 6.2+ Application startup fail - mappingModelPart is null

I also tried adding breakpoint in MappingException class and saw below error message. I tried modifying custAccId to 'id' but it doesn't fix the issue. property [id] not found on entity [com.foo.mysvc.customerdata.model.CustomerAccount]

Below is the entity class in question. Any help is greatly appreciated.

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;
}```


Solution

  • Update: my colleague found the issue and the culprit was an @SqlResultSetMapping annotation in one of the entity classes but not being used to any named query.

    I hope this helps to anyone facing the same issue. Hibernate 6 added validations to unused mapping annotations so you can check those because hibernate doesn't display helpful error message at all for these type of exceptions. Could have just displayed an error "Result set mapping annotation is declared but unused" or something similar.