Skip to content

Spring Boot 4.0.1 + GraalVM: processAot Fails with hibernate.hbm2ddl.auto=update (Requires AOT Task Configuration Workaround) #4130

@mingchiuli

Description

@mingchiuli

hibernate-core version: 7.2.0.FINAL

Description

When using Spring Boot 4.0.1 with GraalVM native image compilation (AOT processing), configuring Hibernate's hbm2ddl.auto=update triggers a fatal error during the processAot Gradle task. The error occurs because Hibernate attempts to access a JDBC connection during AOT processing (for schema migration) but no connection is available at this stage.

Environment

  • Spring Boot: 4.0.1
  • Hibernate: 7.2.0.Final (bundled with Spring Boot 4.0.1)
  • GraalVM: Any version (reproducible with latest GraalVM CE 21/25)
  • Build Tool: Gradle (Kotlin/Groovy DSL)
  • JPA Configuration: spring.jpa.properties.hibernate.hbm2ddl.auto=update

Reproduction Steps

  1. Create a new Spring Boot 4.0.1 project with Spring Data JPA dependency.
  2. Add the following configuration to application.yml/application.properties:
    spring:
      jpa:
        properties:
          hibernate:
            hbm2ddl:
              auto: update
  3. Add a simple JPA entity and repository (e.g., User entity + UserRepository).
  4. Run GraalVM AOT processing via Gradle: ./gradlew processAot (or build native image with ./gradlew nativeCompile).

Expected Behavior

AOT processing completes successfully, and the native image can be built without errors.

Actual Behavior

The processAot task fails with an AotProcessingException caused by a Hibernate PersistenceException ("Unable to build Hibernate SessionFactory") and a root cause of "The application must supply JDBC connections".

Full Error Stack Trace Snippet

> Task :processAot FAILED

Exception in thread "main" org.springframework.beans.factory.aot.AotProcessingException: Error executing 'org.springframework.beans.factory.aot.BeanRegistrationsAotProcessor': Unable to build Hibernate SessionFactory  [persistence unit: AotMetamodel] 
    at org.springframework.context.aot.BeanFactoryInitializationAotContributions.processAheadOfTime(BeanFactoryInitializationAotContributions.java:86)
    ...
Caused by: jakarta.persistence.PersistenceException: Unable to build Hibernate SessionFactory  [persistence unit: AotMetamodel] 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1461)
    ...
Caused by: java.lang.UnsupportedOperationException: The application must supply JDBC connections
    at org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:39)
    ...

Workaround

Adding the following Gradle configuration to disable schema generation during AOT processing resolves the issue:

// Gradle Kotlin DSL
tasks.withType<ProcessAot>().configureEach {
    systemProperty("spring.jpa.properties.jakarta.persistence.schema-generation.database.action", "none")
}

Root Cause Analysis

During AOT processing, Spring Data JPA attempts to initialize a Hibernate SessionFactory for metamodel generation. When hibernate.hbm2ddl.auto=update is set, Hibernate tries to connect to the database to perform schema migration—but no JDBC connection is available in the AOT processing context (this is a build-time step, not runtime).

The workaround disables schema generation only during AOT processing by setting jakarta.persistence.schema-generation.database.action=none, which prevents Hibernate from attempting a database connection during build time.

Request

  • Fix Spring Boot 4.0.1 to handle hibernate.hbm2ddl.auto=update gracefully during AOT processing (without requiring manual task configuration).
  • Automatically disable Hibernate schema generation during AOT processing (or provide a built-in property to control this behavior).
  • Update Spring Boot documentation to note this limitation/workaround for GraalVM + Hibernate users.

Additional Context

This issue is specific to Spring Boot 4.0.1 (and possibly 4.0.x) – earlier versions (e.g., 3.2.x) may not exhibit this behavior due to differences in AOT processing for JPA. The workaround is functional but non-intuitive for users migrating to Spring Boot 4.0.x with GraalVM.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions