spring-native
spring-native copied to clipboard
Query method on JPARepository is failing
Spring Boot 2.6.4 Spring Native 0.11.3 Kotlin 1.6.10
I am trying to create a demo using Spring Data JPA, but I got the following error.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerRepository': Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.Optional com.example.springnativedemo.CustomerRepository.findByName(java.lang.String)! Reason: Incomplete hierarchy for class CustomerRepository, unresolved classes [org.springframework.data.jpa.repository.JpaRepository]; nested exception is java.lang.IllegalStateException: Incomplete hierarchy for class CustomerRepository, unresolved classes [org.springframework.data.jpa.repository.JpaRepository]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[na:na]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:934) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[na:na]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[na:na]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[com.example.springnativedemo.SpringNativeDemoApplicationKt:2.6.4]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[com.example.springnativedemo.SpringNativeDemoApplicationKt:2.6.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[com.example.springnativedemo.SpringNativeDemoApplicationKt:2.6.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[com.example.springnativedemo.SpringNativeDemoApplicationKt:2.6.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[com.example.springnativedemo.SpringNativeDemoApplicationKt:2.6.4]
at com.example.springnativedemo.SpringNativeDemoApplicationKt.main(SpringNativeDemoApplication.kt:13) ~[na:na]
Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.Optional com.example.springnativedemo.CustomerRepository.findByName(java.lang.String)! Reason: Incomplete hierarchy for class CustomerRepository, unresolved classes [org.springframework.data.jpa.repository.JpaRepository]; nested exception is java.lang.IllegalStateException: Incomplete hierarchy for class CustomerRepository, unresolved classes [org.springframework.data.jpa.repository.JpaRepository]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:106) ~[na:na]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(QueryExecutorMethodInterceptor.java:94) ~[na:na]
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
at java.util.Iterator.forEachRemaining(Iterator.java:133) ~[na:na]
at java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1061) ~[na:na]
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845) ~[na:na]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.mapMethodsToQuery(QueryExecutorMethodInterceptor.java:96) ~[na:na]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$new$0(QueryExecutorMethodInterceptor.java:86) ~[na:na]
at java.util.Optional.map(Optional.java:260) ~[na:na]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.<init>(QueryExecutorMethodInterceptor.java:86) ~[na:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:364) ~[na:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:322) ~[com.example.springnativedemo.SpringNativeDemoApplicationKt:2.6.2]
at org.springframework.data.util.Lazy.getNullable(Lazy.java:230) ~[na:na]
at org.springframework.data.util.Lazy.get(Lazy.java:114) ~[na:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:328) ~[com.example.springnativedemo.SpringNativeDemoApplicationKt:2.6.2]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:144) ~[com.example.springnativedemo.SpringNativeDemoApplicationKt:2.6.2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[na:na]
... 16 common frames omitted
Caused by: java.lang.IllegalStateException: Incomplete hierarchy for class CustomerRepository, unresolved classes [org.springframework.data.jpa.repository.JpaRepository]
at kotlin.reflect.jvm.internal.impl.descriptors.runtime.components.RuntimeErrorReporter.reportIncompleteHierarchy(RuntimeErrorReporter.kt:26) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassTypeConstructor.computeSupertypes(DeserializedClassDescriptor.kt:228) ~[na:na]
at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor$supertypes$1.invoke(AbstractTypeConstructor.kt:77) ~[na:na]
at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor$supertypes$1.invoke(AbstractTypeConstructor.kt:76) ~[na:na]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408) ~[na:na]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:481) ~[na:na]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:512) ~[na:na]
at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:26) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.getNonDeclaredVariableNames(DeserializedClassDescriptor.kt:336) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation$variableNames$2.invoke(DeserializedMemberScope.kt:262) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation$variableNames$2.invoke(DeserializedMemberScope.kt:261) ~[na:na]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408) ~[na:na]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527) ~[na:na]
at kotlin.reflect.jvm.internal.impl.storage.StorageKt.getValue(storage.kt:42) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.getVariableNames(DeserializedMemberScope.kt:261) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.addFunctionsAndPropertiesTo(DeserializedMemberScope.kt:349) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope.computeDescriptors(DeserializedMemberScope.kt:115) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope$allDescriptors$1.invoke(DeserializedClassDescriptor.kt:257) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope$allDescriptors$1.invoke(DeserializedClassDescriptor.kt:256) ~[na:na]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408) ~[na:na]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527) ~[na:na]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.getContributedDescriptors(DeserializedClassDescriptor.kt:267) ~[na:na]
at kotlin.reflect.jvm.internal.impl.resolve.scopes.ResolutionScope$DefaultImpls.getContributedDescriptors$default(ResolutionScope.kt:50) ~[na:na]
at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.getMembers(KDeclarationContainerImpl.kt:56) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl$Data$declaredNonStaticMembers$2.invoke(KClassImpl.kt:162) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl$Data$declaredNonStaticMembers$2.invoke(KClassImpl.kt:162) ~[na:na]
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93) ~[na:na]
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl$Data.getDeclaredNonStaticMembers(KClassImpl.kt:162) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl$Data$allNonStaticMembers$2.invoke(KClassImpl.kt:171) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl$Data$allNonStaticMembers$2.invoke(KClassImpl.kt:171) ~[na:na]
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93) ~[na:na]
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl$Data.getAllNonStaticMembers(KClassImpl.kt:171) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl$Data$allMembers$2.invoke(KClassImpl.kt:177) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl$Data$allMembers$2.invoke(KClassImpl.kt:177) ~[na:na]
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93) ~[na:na]
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl$Data.getAllMembers(KClassImpl.kt:177) ~[na:na]
at kotlin.reflect.jvm.internal.KClassImpl.getMembers(KClassImpl.kt:195) ~[na:na]
at kotlin.reflect.full.KClasses.getFunctions(KClasses.kt:89) ~[com.example.springnativedemo.SpringNativeDemoApplicationKt:1.6.10-release-923(1.6.10)]
at kotlin.reflect.jvm.ReflectJvmMapping.getKotlinFunction(ReflectJvmMapping.kt:136) ~[na:na]
at org.springframework.data.util.KotlinReflectionUtils.findKotlinFunction(KotlinReflectionUtils.java:95) ~[na:na]
at org.springframework.data.util.KotlinReflectionUtils.isSuspend(KotlinReflectionUtils.java:111) ~[na:na]
at org.springframework.data.repository.core.support.AbstractRepositoryMetadata.getReturnType(AbstractRepositoryMetadata.java:90) ~[na:na]
at org.springframework.data.repository.core.support.DefaultRepositoryInformation.getReturnType(DefaultRepositoryInformation.java:254) ~[na:na]
at org.springframework.data.repository.query.QueryMethod.potentiallyUnwrapReturnTypeFor(QueryMethod.java:282) ~[na:na]
at org.springframework.data.repository.query.QueryMethod.<init>(QueryMethod.java:81) ~[na:na]
at org.springframework.data.jpa.repository.query.JpaQueryMethod.<init>(JpaQueryMethod.java:107) ~[na:na]
at org.springframework.data.jpa.repository.query.DefaultJpaQueryMethodFactory.build(DefaultJpaQueryMethodFactory.java:44) ~[na:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:87) ~[na:na]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:102) ~[na:na]
... 38 common frames omitted
Seems like custom query methods are not supported in the CustomerRepository interface because if you remove the method, it works.
interface CustomerRepository: JpaRepository<Customer, String> {
fun findByName(name: String): Optional<Customer>
}
You can find a demo here to reproduce the error.
@christophstrobl @schauder Could you please have a look to this issue?
As discussed with @christophstrobl, seems to work with:
@TypeHint(types = [
org.springframework.data.jpa.repository.JpaRepository::class,
org.springframework.data.repository.PagingAndSortingRepository::class,
org.springframework.data.repository.CrudRepository::class,
org.springframework.data.repository.Repository::class,
org.springframework.data.repository.query.QueryByExampleExecutor::class,
java.util.Optional::class,
FluentQuery::class,
FluentQuery.FetchableFluentQuery::class
], access = [TypeAccess.QUERY_PUBLIC_METHODS])
So it seems we can add transitively the types to make Kotlin reflection happy in query mode to keep the footprint small.
It works, just needed to add java.time.OffsetDateTime as one of my query methods use it
Blocked on https://github.com/oracle/graal/issues/4418.
Spring Native is now superseded by Spring Boot 3 official native support, see the related reference documentation for more details.
As a consequence, I am closing this issue, and recommend trying your use case with latest Spring Boot 3 version. If you still experience the issue reported here, please open an issue directly on the related Spring project (Spring Framework, Data, Security, Boot, Cloud, etc.) with a reproducer.
Thanks for your contribution on the experimental Spring Native project, we hope you will enjoy the official native support introduced by Spring Boot 3.