有啥方法可以通过 Spring Boot JPA Repository 接收 List<LocalDate>

Posted

技术标签:

【中文标题】有啥方法可以通过 Spring Boot JPA Repository 接收 List<LocalDate>【英文标题】:Is there any way to receive List<LocalDate> by Spring Boot JPA Repository有什么方法可以通过 Spring Boot JPA Repository 接收 List<LocalDate> 【发布时间】:2020-05-31 23:18:11 【问题描述】:

我正在尝试接收实体的 LocalDate 属性。但我得到了一个无法转换类型的异常。我正在尝试通过 Spring Boot JPA 文档搜索答案,但没有任何帮助。

Gradle 配置

plugins 
    id 'org.springframework.boot' version '2.2.0.RELEASE'
    id 'io.spring.dependency-management' version '1.0.7.RELEASE'
    id 'java'


configurations 
    compileOnly 
        extendsFrom annotationProcessor
    


dependencies 
    implementation group: 'com.h2database', name: 'h2', version: '1.4.200'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation('org.springframework.boot:spring-boot-starter-test')


配置

spring:
  datasource:
    driver-class-name: org.h2.Driver
    username: sa
    password: sa
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
    hikari:
      maximum-pool-size: 100

  jpa:
    generate-ddl: true
    show-sql: true
    hibernate:
      ddl-auto: create-drop

实体

@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Entity
@Table(name = "db_test")
public class TestEntity 
    @Id
    private String id;
    private Integer age;
    private LocalDate birthday;

存储库

@Repository
public interface TestRepository extends JpaRepository<TestEntity, String> 

    @Query(nativeQuery = true, value = "SELECT DISTINCT birthday from db_test")
    List<LocalDate> findAllBirthday();


测试方法

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestRepositoryTest 

    @Autowired
    private TestRepository testRepository;

    @Test
    public void findAllBirthday() 
        TestEntity entity = new TestEntity("OK", 1, LocalDate.parse("2019-01-01"));
        testRepository.save(entity);

        List<LocalDate> result = testRepository.findAllBirthday();
        Assert.assertEquals(1, result.size());
    

例外

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.util.ArrayList<?>] to type [@org.springframework.data.jpa.repository.Query java.util.List<java.time.LocalDate>] for value '[2019-01-01, 2019-01-02, 2019-01-03]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.sql.Date] to type [@org.springframework.data.jpa.repository.Query java.time.LocalDate]
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:212)
    at org.springframework.data.repository.core.support.QueryExecutionResultHandler.postProcessInvocationResult(QueryExecutionResultHandler.java:166)
    at org.springframework.data.repository.core.support.QueryExecutionResultHandler.postProcessInvocationResult(QueryExecutionResultHandler.java:77)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605)


附加信息:

也许我没有很好地表达我的想法。这是我的操作:

    使用 H2 作为默认数据库。 编写 JUnit4 测试方法。 在 Spring Boot 测试环境下运行测试。 希望有返回列表,但只有例外。

【问题讨论】:

尝试用 @Column(columnDefinition = "DATE") 注释生日(最好的猜测来自 ***.com/questions/54840769/… 和 baeldung.com/jpa-java-time) 这取决于你是如何定义你的表结构的。如果您使用的是 mysql 和 DATETIME 列。然后您必须使用 java.sql.Timestamp 来检索该信息,然后您可以根据您选择的 DateFormatter 进行转换 【参考方案1】:

如何在数据库中创建字段?如果您使用 MySQL,您的生日字段数据类型必须为 DATE! 否则,由于强制转换,这是预期的。

【讨论】:

我使用了create-drop 策略。我正在尝试调试以找出答案。返回类型是 List,并且将 List 上的异常转换为 List。因为JPA的转换服务是一个静态服务对象,它的转换器不包含任何Timestamp translate方法。 你能从你的数据库中验证我的日期格式并输入吗?可能是 YYYY-MM-DD【参考方案2】:

它不会由您自己解决!

Spring JPA 通过转换器转换数据库数据。并且当您查询 Timestamp 数据时,默认情况下不会将 Timestamp 转换为 LocalDate。

此外,JPA 的转换器不像 Spring MVC 的,自定义转换器不会添加到 JPA 转换器中,它始终使用系统默认的静态转换器。

【讨论】:

以上是关于有啥方法可以通过 Spring Boot JPA Repository 接收 List<LocalDate>的主要内容,如果未能解决你的问题,请参考以下文章

spring boot系列spring boot 配置spring data jpa (查询方法)

Spring Boot + JPA + mysql ...错误的方法?

Spring boot JPA

Spring boot JPA

Spring boot JPA

使用 Spring Boot 框架对基于 Spring JPA 的 DAO 进行分层的正确方法