micronaut-projects / micronaut-projects/micronaut-data

Native image with JPA+Hibernate throws exception in runtime

Open
#3,579 0 comments 0 reactions 0 assignees View on GitHub
type: bug
Dominant language
Java
Stars
482
Forks
229
Avg merge
1d 7h
Merged PRs (30d)
32

Description

### Expected Behavior

## Background
1. micronaut 4.10.1 + graalvm 25 + musl
2. dependencies:
```
implementation(mn.micronaut.data.hibernate.jpa) // 4.14.0
implementation(mn.micronaut.jdbc.hikari)
implementation(mn.micronaut.hibernate.jpa). // 6.3.1
```
## Behaviour

1. build project to native image successfully, `./gradlew :webservice:nativeCompile`
2. it is ok for **repository query operation**.
3. fail to execute **repository save operation**.

## The entity is:

```
import io.micronaut.configuration.hibernate.jpa.proxy.GenerateProxy;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Set;

@Getter
@Setter
@NoArgsConstructor
@GenerateProxy
@Entity
@Table(name = "project")
public class ProjectEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;

@Column(name = "name", nullable = false, unique = true, length = 128)
private String name;

@Column(name = "exclusions", nullable = false, columnDefinition = "TEXT")
private String exclusions;

@OneToMany(mappedBy = "project", fetch = FetchType.LAZY)
private Set branches;
}
```
## The error message is:

```
08:35:03.209 [virtual-executor--891628443] ERROR i.m.http.server.RouteExecutor - Unexpected error occurred: Cannot reflectively instantiate the array class 'java.util.function.Function[]'. To allow this operation, add the following to the 'reflection' section of 'reachability-metadata.json' and rebuild the native image:

  {
    "type": "java.util.function.Function[]"
  }

The 'reachability-metadata.json' file should be located in 'META-INF/native-image///' of your project. For further help, see https://www.graalvm.org/latest/reference-manual/native-image/metadata/#reflection
org.graalvm.nativeimage.MissingReflectionRegistrationError: Cannot reflectively instantiate the array class 'java.util.function.Function[]'. To allow this operation, add the following to the 'reflection' section of 'reachability-metadata.json' and rebuild the native image:

  {
    "type": "java.util.function.Function[]"
  }

The 'reachability-metadata.json' file should be located in 'META-INF/native-image///' of your project. For further help, see https://www.graalvm.org/latest/reference-manual/native-image/metadata/#reflection
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.MissingReflectionRegistrationUtils.reportArrayInstantiation(MissingReflectionRegistrationUtils.java:145)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.graal.snippets.SubstrateAllocationSnippets.arrayHubErrorStub(SubstrateAllocationSnippets.java:420)
        at org.hibernate.internal.util.collections.StandardStack.push(StandardStack.java:48)
        at org.hibernate.internal.util.collections.StandardStack.(StandardStack.java:37)
        at org.hibernate.query.results.DomainResultCreationStateImpl.(DomainResultCreationStateImpl.java:84)
        at org.hibernate.generator.values.internal.GeneratedValuesMappingProducer.resolve(GeneratedValuesMappingProducer.java:52)
        at org.hibernate.generator.values.internal.GeneratedValuesHelper.readGeneratedValues(GeneratedValuesHelper.java:160)
        at org.hibernate.generator.values.internal.GeneratedValuesHelper.getGeneratedValues(GeneratedValuesHelper.java:102)
        at org.hibernate.id.insert.GetGeneratedKeysDelegate.performMutation(GetGeneratedKeysDelegate.java:121)
        at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:47)
        at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
        at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:194)
        at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:132)
        at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:95)
        at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:85)
        at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:682)
        at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:293)
        at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:274)
        at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:324)
        at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:394)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:308)
        at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:224)
        at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:136)
        at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:177)
        at org.hibernate.event.internal.DefaultPersistEventListener.persist(DefaultPersistEventListener.java:95)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:79)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55)
        at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:761)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:745)
        at io.micronaut.data.hibernate.operations.HibernateJpaOperations.lambda$persist$11(HibernateJpaOperations.java:417)
        at io.micronaut.data.hibernate.operations.HibernateJpaOperations.lambda$executeWrite$24(HibernateJpaOperations.java:667)
        at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.lambda$execute$2(AbstractPropagatedStatusTransactionOperations.java:68)
        at io.micronaut.transaction.TransactionCallback.apply(TransactionCallback.java:37)
        at io.micronaut.transaction.support.AbstractTransactionOperations.executeTransactional(AbstractTransactionOperations.java:333)
        at io.micronaut.transaction.support.AbstractTransactionOperations.lambda$openConnectionAndExecuteTransaction$5(AbstractTransactionOperations.java:302)
        at io.micronaut.data.connection.support.AbstractConnectionOperations.withExistingConnectionInternal(AbstractConnectionOperations.java:152)
        at io.micronaut.data.connection.support.AbstractConnectionOperations.execute(AbstractConnectionOperations.java:116)
        at io.micronaut.transaction.support.AbstractTransactionOperations.openConnectionAndExecuteTransaction(AbstractTransactionOperations.java:301)
        at io.micronaut.transaction.support.AbstractTransactionOperations.executeWithExistingTransaction(AbstractTransactionOperations.java:248)
        at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:131)
        at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:125)
        at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.execute(AbstractPropagatedStatusTransactionOperations.java:65)
        at io.micronaut.transaction.TransactionOperations.executeWrite(TransactionOperations.java:87)
        at io.micronaut.data.hibernate.operations.HibernateJpaOperations.executeWrite(HibernateJpaOperations.java:667)
        at io.micronaut.data.hibernate.operations.HibernateJpaOperations.persist(HibernateJpaOperations.java:403)
        at io.micronaut.data.runtime.intercept.DefaultSaveEntityInterceptor.intercept(DefaultSaveEntityInterceptor.java:45)
        at io.micronaut.data.runtime.intercept.DataIntroductionAdvice.intercept(DataIntroductionAdvice.java:84)
        at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:143)
        at com.csg.i18n.web.repository.ProjectRepository$Intercepted.save(Unknown Source)
        at com.csg.i18n.web.service.ProjectService.createProject(ProjectService.java:66)
        at com.csg.i18n.web.service.$ProjectService$Definition$Intercepted.$$access$$createProject(Unknown Source)
        at com.csg.i18n.web.service.$ProjectService$Definition$Exec.dispatch(Unknown Source)
        at io.micronaut.context.AbstractExecutableMethodsDefinition$DispatchedExecutableMethod.invoke(AbstractExecutableMethodsDefinition.java:456)
        at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:134)
        at io.micronaut.transaction.interceptor.TransactionalInterceptor.lambda$intercept$5(TransactionalInterceptor.java:140)
        at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.lambda$execute$2(AbstractPropagatedStatusTransactionOperations.java:68)
        at io.micronaut.transaction.TransactionCallback.apply(TransactionCallback.java:37)
        at io.micronaut.transaction.support.AbstractTransactionOperations.executeTransactional(AbstractTransactionOperations.java:333)
        at io.micronaut.transaction.support.AbstractTransactionOperations.executeWithNewTransaction(AbstractTransactionOperations.java:318)
        at io.micronaut.transaction.support.AbstractTransactionOperations.executeNew(AbstractTransactionOperations.java:235)
        at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:137)
        at io.micronaut.transaction.support.AbstractTransactionOperations.lambda$doExecute$0(AbstractTransactionOperations.java:122)
        at io.micronaut.data.connection.support.AbstractConnectionOperations.executeWithNewConnection(AbstractConnectionOperations.java:167)
        at io.micronaut.data.connection.support.AbstractConnectionOperations.execute(AbstractConnectionOperations.java:114)
        at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:120)
        at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.execute(AbstractPropagatedStatusTransactionOperations.java:65)
        at io.micronaut.transaction.interceptor.TransactionalInterceptor.intercept(TransactionalInterceptor.java:140)
        at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:143)
        at com.csg.i18n.web.service.$ProjectService$Definition$Intercepted.createProject(Unknown Source)
        at com.csg.i18n.web.controller.ProjectController.createProject(ProjectController.java:107)
        at com.csg.i18n.web.controller.$ProjectController$Definition$Exec.dispatch(Unknown Source)
        at io.micronaut.context.AbstractExecutableMethodsDefinition$DispatchedExecutableMethod.invokeUnsafe(AbstractExecutableMethodsDefinition.java:461)
        at io.micronaut.context.DefaultBeanContext$BeanContextUnsafeExecutionHandle.invokeUnsafe(DefaultBeanContext.java:4454)
        at io.micronaut.web.router.AbstractRouteMatch.execute(AbstractRouteMatch.java:272)
        at io.micronaut.web.router.DefaultUriRouteMatch.execute(DefaultUriRouteMatch.java:38)
        at io.micronaut.http.server.RouteExecutor.executeRouteAndConvertBody(RouteExecutor.java:466)
        at io.micronaut.http.server.RouteExecutor.lambda$callRoute$5(RouteExecutor.java:443)
        at io.micronaut.core.execution.ExecutionFlow.lambda$async$0(ExecutionFlow.java:92)
        at io.micronaut.core.propagation.PropagatedContext.lambda$wrap$3(PropagatedContext.java:232)
        at java.base@25/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
        at java.base@25/java.util.concurrent.FutureTask.run(FutureTask.java:328)
        at java.base@25/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:309)
        at java.base@25/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
        at java.base@25/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
        at java.base@25/java.lang.Thread.runWith(Thread.java:1487)
        at java.base@25/java.lang.VirtualThread.run(VirtualThread.java:456)
        at java.base@25/java.lang.VirtualThread$VThreadContinuation$1.run(VirtualThread.java:248)
```

### Actual Behaviour

_No response_

### Steps To Reproduce

_No response_

### Environment Information

- Build in OS: ubuntu 24.04
- Run in OS: ubuntu 20.04
- Java: Graalvm 25 (https://download.bell-sw.com/vm/25.0.1/bellsoft-liberica-vm-openjdk25.0.1+12-25.0.1+1-linux-amd64.tar.gz)

### Example Application

_No response_

### Version

4.10.1

Contributor guide

Open the contributing guide

Research direction

Reproduce the failure with the reported nativeCompile command and a repository save using ProjectEntity. Start at HibernateJpaOperations.persist and the Hibernate generated-values stack frames, then verify that the native image can complete the save operation without the Function[] reflection error.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.