Affects: Spring 6.0.11 / Spring Boot 3.1.2


Assume an application with the following components: - Spring Boot 3.1.2 - Spring JPA - Spring Web - H2 as a database (for tests, I don't think the DB affects this issue)

Let this application have a controller with an endpoint accepting a MultipartFile that calls an @Transactional method. This controller just needs to exist, it does not need to be called. The application has an entity with a String field (@Id) and a corresponding CrudRepository with a getBy<attribute name> method that is executed in a @SpringBootTest.

When running the tests of this application with native-image, an error like the following occurs:

com.oracle.svm.core.jdk.UnsupportedFeatureError: Proxy class defined by interfaces [interface org.hibernate.query.hql.spi.SqmQueryImplementor, interface org.hibernate.query.sqm.internal.SqmInterpretationsKey$InterpretationsKeySource, interface org.hibernate.query.spi.DomainQueryExecutionContext, interface org.hibernate.query.SelectionQuery, interface org.hibernate.query.CommonQueryContract] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
       org.graalvm.nativeimage.builder/com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:92)
       org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.proxy.DynamicProxySupport.getProxyClass(DynamicProxySupport.java:171)
       java.base@17.0.7/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:47)
       java.base@17.0.7/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:1037)
       org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:316)
       jdk.proxy4/jdk.proxy4.$Proxy52.createQuery(Unknown Source)
       org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:297)
       org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:242)
       org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:113)
       org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:234)

Reproducer: https://github.com/danthe1st/spring-proxy-missing-repro Build logs with error: https://github.com/danthe1st/spring-proxy-missing-repro/actions/runs/5647960364/job/15299138251

Comment From: snicoll

It's unclear to me why @Transactional and Multipart is associated with this issue. Are you saying that the error goes away if you remove the use of those?

The hibernate enhance plugin has not been applied to the reproducer so that's one step you should take before going any further. Please fix the reproducer to use it (check start.spring.io with JPA and GraalVM for an example if necessary).

Comment From: danthe1st

I have updated the reproducer.

Comment From: snicoll

Thanks. These are hibernate metadata so I am afraid there's not much we can do. This looks like a duplicate of https://github.com/oracle/graalvm-reachability-metadata/issues/324

Comment From: damianopittori

I had the same issue after upgrading to SpringBoot v3.1.2, only one of my services calling a specific repo was throwing that exception, I managed to solve ( while waiting for hibernate metadata ) by adding @Transactional(readOnly = true) on that service since it was the only one out of transaction. Also, the repo call is under another layer of @Cacheable service and the exception was raised even if the query result was previously cached.

Comment From: sbrannen

It turns out this was actually a:

  • Duplicate of #31050