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