Description
Describe the bug
The example is under the repository https://github.com/FranPregernik/springdoc-npe-issue
In the example I have a Bank entity (id, code, name) and a standard BankRepository (JpaRepository) with an additional interface CodeLookupRepository with a method findOneByCode.
A subset of my entites have the code column and I need to use this findOneByCode method elsewhere in code (there I am using CodeLookupRepository instead of the concrete BankRepository).
When I have the same findOnByCode inside BankRepository the OpenApi is generated.
When I remove it from BankRepository and just have it in CodeLookupRepository then a NPE occurs:
2021-01-04 10:00:44.584 ERROR 733105 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
at java.lang.Class.isAssignableFrom(Native Method) ~[na:1.8.0_265]
at org.springdoc.data.rest.core.DataRestResponseService.findSearchReturnType(DataRestResponseService.java:171) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.data.rest.core.DataRestResponseService.buildSearchResponse(DataRestResponseService.java:88) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.data.rest.core.DataRestOperationService.buildSearchOperation(DataRestOperationService.java:196) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.data.rest.core.DataRestOperationService.buildOperation(DataRestOperationService.java:121) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.data.rest.core.DataRestRouterOperationService.buildRouterOperation(DataRestRouterOperationService.java:238) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.data.rest.core.DataRestRouterOperationService.buildRouterOperationList(DataRestRouterOperationService.java:185) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.data.rest.core.DataRestRouterOperationService.buildSearchRouterOperationList(DataRestRouterOperationService.java:140) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.lambda$findSearchControllers$15(SpringRepositoryRestResourceProvider.java:299) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) ~[na:1.8.0_265]
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) ~[na:1.8.0_265]
at java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1628) ~[na:1.8.0_265]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[na:1.8.0_265]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[na:1.8.0_265]
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[na:1.8.0_265]
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[na:1.8.0_265]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_265]
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485) ~[na:1.8.0_265]
at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.findSearchControllers(SpringRepositoryRestResourceProvider.java:299) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.findSearchResourceMappings(SpringRepositoryRestResourceProvider.java:279) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.getRouterOperations(SpringRepositoryRestResourceProvider.java:221) ~[springdoc-openapi-data-rest-1.5.2.jar:1.5.2]
at org.springdoc.webmvc.api.OpenApiResource.getPaths(OpenApiResource.java:217) ~[springdoc-openapi-webmvc-core-1.5.2.jar:1.5.2]
at org.springdoc.api.AbstractOpenApiResource.getOpenApi(AbstractOpenApiResource.java:283) ~[springdoc-openapi-common-1.5.2.jar:1.5.2]
at org.springdoc.webmvc.api.OpenApiResource.openapiJson(OpenApiResource.java:172) ~[springdoc-openapi-webmvc-core-1.5.2.jar:1.5.2]
at org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson(OpenApiWebMvcResource.java:116) ~[springdoc-openapi-webmvc-core-1.5.2.jar:1.5.2]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_265]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_265]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_265]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_265]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.2.jar:5.3.2]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.2.jar:5.3.2]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.2.jar:5.3.2]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.2.jar:5.3.2]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.2.jar:5.3.2]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.2.jar:5.3.2]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061) ~[spring-webmvc-5.3.2.jar:5.3.2]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961) ~[spring-webmvc-5.3.2.jar:5.3.2]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.2.jar:5.3.2]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.2.jar:5.3.2]
...
I traced this to the resolve method where it identifies the return type as EntityT
and calling getRawClass()
on that type returns a null.
To Reproduce
Steps to reproduce the behavior:
- Checkout repo
- Run spring boot app
- Open the standard swagger-ui.html
Expected behavior
- I expect the
CodeLookupRepository<EntityT, KeyT>
method return types to be resolved just like the standardJpaRepository<Entity, ID>
generics are resolved - Having the
findOneByCode
method inBankRepository
or inCodeLookupRepository
should produce the same OpenApi spec
** Additional info **
This is an amazing project! Thank you!