Skip to content

findByNameContainingIgnoreCaseAndDateBefore throw NullPointerException #2010

Closed
@zctmdc

Description

@zctmdc

Describe the bug

  • If you are reporting a bug, please help to speed up problem diagnosis by providing as
    much information as possible:
  • A clear and concise description of what the bug is: the title of an issue is not enough

To Reproduce
Steps to reproduce the behavior:

  1. creat project

image

  1. use OpenAPI

  2. code

  3. run

  4. open http://localhost:8080/swagger-ui.html

  5. get erro

image

  • What version of spring-boot you are using?
...
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.6</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
  • What modules and versions of springdoc-openapi are you using?

		<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui -->
		<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-ui</artifactId>
			<version>1.6.14</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-data-rest -->
		<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-data-rest</artifactId>
			<version>1.6.14</version>
		</dependency>
  • What is the actual and the expected result using OpenAPI Description (yml or json)?
    data:
        rest:
            base-path: /api/rest
  • Provide with a sample code (HelloController) or Test that reproduces the problem
    response status is 500 /v3/api-docs/JLYShop-public
    Expected behavior

  • A clear and concise description of what you expected to happen.

  • What is the expected result using OpenAPI Description (yml or json)?

        /**
         * 根据商品名称模糊查询指定日期前的商品信息
         * 
         * @param name 商品名称
         * @param end  指定日期结束
         * @return 商品信息列表
         */
        List<ProductEntity> findByNameContainingIgnoreCaseAndDateBefore(
                        @Parameter(name = "商品名称", required = true) String name,
                        @Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sun Dec 18 00:14:20 CST 2022
There was an unexpected error (type=Internal Server Error, status=500).
Cannot invoke "org.springframework.data.repository.query.Param.value()" because the return value of "java.lang.reflect.Parameter.getAnnotation(java.lang.Class)" is null
java.lang.NullPointerException: Cannot invoke "org.springframework.data.repository.query.Param.value()" because the return value of "java.lang.reflect.Parameter.getAnnotation(java.lang.Class)" is null
	at org.springdoc.data.rest.core.DataRestOperationService.getParameterType(DataRestOperationService.java:241)
	at org.springdoc.data.rest.core.DataRestOperationService.buildSearchOperation(DataRestOperationService.java:208)
	at org.springdoc.data.rest.core.DataRestOperationService.buildOperation(DataRestOperationService.java:135)
	at org.springdoc.data.rest.core.DataRestRouterOperationService.buildRouterOperation(DataRestRouterOperationService.java:287)
	at org.springdoc.data.rest.core.DataRestRouterOperationService.buildRouterOperation(DataRestRouterOperationService.java:226)
	at org.springdoc.data.rest.core.DataRestRouterOperationService.buildRouterOperationList(DataRestRouterOperationService.java:192)
	at org.springdoc.data.rest.core.DataRestRouterOperationService.buildSearchRouterOperationList(DataRestRouterOperationService.java:147)
	at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.lambda$findSearchControllers$13(SpringRepositoryRestResourceProvider.java:383)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
	at java.base/java.util.HashMap$ValueSpliterator.forEachRemaining(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.findSearchControllers(SpringRepositoryRestResourceProvider.java:383)
	at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.findSearchResourceMappings(SpringRepositoryRestResourceProvider.java:362)
	at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.getRouterOperations(SpringRepositoryRestResourceProvider.java:276)
	at org.springdoc.webmvc.api.OpenApiResource.lambda$getPaths$1(OpenApiResource.java:169)
	at java.base/java.util.Optional.ifPresent(Unknown Source)
	at org.springdoc.webmvc.api.OpenApiResource.lambda$getPaths$2(OpenApiResource.java:168)
	at java.base/java.util.Optional.ifPresent(Unknown Source)
	at org.springdoc.webmvc.api.OpenApiResource.getPaths(OpenApiResource.java:164)
	at org.springdoc.api.AbstractOpenApiResource.getOpenApi(AbstractOpenApiResource.java:364)
	at org.springdoc.webmvc.api.OpenApiResource.openapiJson(OpenApiResource.java:139)
	at org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson(OpenApiWebMvcResource.java:116)
	at org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource.openapiJson(MultipleOpenApiWebMvcResource.java:88)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:670)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:769)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Unknown Source)

Screenshots
If applicable, add screenshots to help explain your problem.

@Hidden not working
image

This can work:
image
This work not very good:
image
image

Additional context
Add any other context about the problem here.

  • entity
@Data
@MappedSuperclass
@DynamicInsert(true)
@DynamicUpdate(true)
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
public abstract class BaseEntity implements Serializable {

    /** SVUDI */
    private static final long serialVersionUID = 1L;

    /** 数据库中的ID */
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "ID", unique = true, nullable = false, insertable = false, updatable = false)
    private Long id;

...

    /**
     * 数据是否合法
     * 
     * @return 是否合法
     */
    public abstract boolean isValid();
}
@Getter
@Setter
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "PRODUCT_ENTITY")
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
public class ProductEntity extends BaseEntity implements Comparable<ProductEntity> {

    /** SVUDI */
    private static final long serialVersionUID = 1L;

    /** 名字. */
    @NotNull
    @Column(nullable = false)
    private String name;

    /** 单价. */
    @NotNull
    @Column(nullable = false)
    private BigDecimal price;

    /** 分类 */
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "CATEGORY_ID")
    private ProductCategoryEntity category;

    /** 日期. */
    @NotNull
    @Column(nullable = false)
    private LocalDate date;

    @Override
    public boolean isValid() {
        return name != null && price != null && date != null;
    }

    /** 根据日期排序 */
    @Override
    public int compareTo(ProductEntity oProduct) {
        return this.getDate().compareTo(oProduct.getDate());
    }

}
  • Swagger3Config
@Configuration
public class Swagger3Config {
    @Bean
    GroupedOpenApi publicApi() {
        return GroupedOpenApi.builder()
                .group("JLYShop-public")
                .pathsToMatch("/api/**")
                .build();
    }

        @Bean
        OpenAPI jlyShopOpenApi() {
                return new OpenAPI()
                                .info(new Info()
                                                .title("JLYShop API")
                                                .description("Spring shop sample application")
                                                .version("v0.0.1")
                                                .license(new License().name("Apache 2.0").url("http://springdoc.org")))
                                .externalDocs(new ExternalDocumentation()
                                                .description("SpringDoc Wiki Documentation")
                                                .url("https://springdoc.org/v2"));
    }

}

/**
 * 商品信息
 * 
 * @author zctmdc
 */
@RepositoryRestResource(path = "product")
public interface ProductRepository extends JpaRepository<ProductEntity, Long> {

        /**
         * 根据商品名称查询商品信息
         * 
         * @param name 商品名称
         * @return 商品信息列表
         */
        List<ProductEntity> findByName(@Parameter(name = "商品名称", required = true) String name);

        /**
         * 根据商品名称查询最新的商品信息
         * 
         * @param name 商品名称
         * @return 商品信息
         */
        ProductEntity findTopByNameOrderByDateDesc(@Parameter(name = "商品名称", required = true) String name);

        /**
         * 根据商品名称模糊查询商品信息并按时间降序排序
         * 
         * @param name 商品名称
         * @return 商品信息列表
         */
        List<ProductEntity> findByNameContainingIgnoreCaseOrderByDateDesc(
                        @Parameter(name = "商品名称", required = true) String name);

        /**
         * 根据商品名称模糊查询商品信息并按时间降序排序
         * 
         * @param name 商品名称
         * @return 商品信息列表
         */
        List<ProductEntity> findByNameContainingIgnoreCase(
                        @Parameter(name = "商品名称", required = true) String name);

        /**
         * 根据商品名称模糊查询指定日期前的商品信息
         * 
         * @param end 指定日期结束
         * @return 商品信息列表
         */
        List<ProductEntity> findByDateBefore(
                        @Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);

        /**
         * 根据商品名称模糊查询指定日期前的商品信息
         * 
         * @param name 商品名称
         * @param end  指定日期结束
         * @return 商品信息列表
         */
        List<ProductEntity> findByNameContainingIgnoreCaseAndDateBefore(
                        @Parameter(name = "商品名称", required = true) String name,
                        @Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);

        /**
         * 查询分类是null的商品信息
         * 
         * @return 商品信息列表
         */
        List<ProductEntity> findByCategoryIsNull();
}

ProductRepository

@RepositoryRestResource(path = "product")
public interface ProductRepository extends JpaRepository<ProductEntity, Long> {

        /**
         * 根据商品名称查询商品信息
         * 
         * @param name 商品名称
         * @return 商品信息列表
         */
        List<ProductEntity> findByName(@Parameter(name = "商品名称", required = true) String name);

        /**
         * 根据商品名称查询最新的商品信息
         * 
         * @param name 商品名称
         * @return 商品信息
         */
        ProductEntity findTopByNameOrderByDateDesc(@Parameter(name = "商品名称", required = true) String name);

        /**
         * 根据商品名称模糊查询商品信息并按时间降序排序
         * 
         * @param name 商品名称
         * @return 商品信息列表
         */
        List<ProductEntity> findByNameContainingIgnoreCaseOrderByDateDesc(
                        @Parameter(name = "商品名称", required = true) String name);

        /**
         * 根据商品名称模糊查询商品信息
         * 
         * @param name 商品名称
         * @return 商品信息列表
         */
        List<ProductEntity> findByNameContainingIgnoreCase(
                        @Parameter(name = "商品名称", required = true) String name);

        /**
         * 查询指定日期前的商品信息
         * 
         * @param end 指定日期结束
         * @return 商品信息列表
         */
        List<ProductEntity> findByDateBefore(
                        @Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);

        /**
         * 根据商品名称模糊查询指定日期前的商品信息
         * 
         * @param name 商品名称
         * @param end  指定日期结束
         * @return 商品信息列表
         */
        List<ProductEntity> findByNameContainingIgnoreCaseAndDateBefore(
                        @Parameter(name = "商品名称", required = true) String name,
                        @Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);

        /**
         * 查询分类是null的商品信息
         * 
         * @return 商品信息列表
         */
        List<ProductEntity> findByCategoryIsNull();
}
  • pom.xml
  <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.6</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>cn.xx</groupId>
	<artifactId>shop</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>shop</name>
	<description>Demo project for HJAJLY SHop</description>
	<properties>
		<java.version>17</java.version>
		<version.fastjson2>2.0.8</version.fastjson2>
		<version.jfiglet>0.0.9</version.jfiglet>
		<version.easyexcel>3.1.1</version.easyexcel>
		<version.sqlite>3.39.2.0</version.sqlite>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-rest</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-rest-hal-explorer</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.mariadb.jdbc</groupId>
			<artifactId>mariadb-java-client</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<!-- javax.validation -->
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
		<dependency>
			<groupId>com.alibaba.fastjson2</groupId>
			<artifactId>fastjson2</artifactId>
			<version>${version.fastjson2}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.github.lalyos/jfiglet -->
		<dependency>
			<groupId>com.github.lalyos</groupId>
			<artifactId>jfiglet</artifactId>
			<version>${version.jfiglet}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>easyexcel</artifactId>
			<version>${version.easyexcel}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
		<dependency>
			<groupId>org.xerial</groupId>
			<artifactId>sqlite-jdbc</artifactId>
			<version>${version.sqlite}</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui -->
		<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-ui</artifactId>
			<version>1.6.14</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-data-rest -->
		<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-data-rest</artifactId>
			<version>1.6.14</version>
		</dependency>


	</dependencies>

	<build>
		<finalName>shop</finalName>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions