查询列表<LocalDate>对于多行失败,但对于一行有效?找不到能够转换的转换器

问题描述 投票:0回答:1

根据 JPA 2.2 支持 Java 8 日期/时间类型 JPA 支持 LocalDate。

查询单行,一切正常。但是当查询多行时,JPA 无法将其转换为列表。

我使用的是最新的 spring 版本 3.3.0

错误日志:

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
 [[...]]


Caused by: 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.GenericConversionService.handleConverterNotFound
(GenericConversionService.java:294)

测试实体.java

@Entity
public class TestEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "TEST_DATE", columnDefinition = "DATE")
    private LocalDate testDate;

    // Setter Getters omitted for readability
}

TestRepository.java

public interface TestRepository extends CrudRepository<TestEntity, Long> {
    @Query(value = "SELECT TEST_DATE FROM TEST_ENTITY", nativeQuery = true)
    LocalDate findBy();
}

TestRepositoryList.java

public interface TestRepositoryList extends CrudRepository<TestEntity, Long> {
    @Query(value = "SELECT TEST_DATE FROM TEST_ENTITY", nativeQuery = true)
    List<LocalDate> findBy();
}

TestApplicationTests.java

    // this works perfectly fine
    @Test
    void testFindBySingle() throws InterruptedException {
        testRepository.save(new TestEntity(1L, LocalDate.now()));
        log.info(String.valueOf(testRepository.findBy()));
    }

    // this fails
    @Test
    void testFindByList() {
        testRepositoryList.save(new TestEntity(1L, LocalDate.now()));
        testRepositoryList.save(new TestEntity(2L, LocalDate.now()));
        log.info(String.valueOf(testRepositoryList.findBy()));
    }
java spring spring-boot hibernate spring-data-jpa
1个回答
0
投票

众所周知的问题是,当我们使用本机查询时,Spring 有时会抱怨转换器。我们不要讨论为什么会发生这种情况,而是集中讨论如何管理它。问题是我们不想从实体中获取所有字段,而只想获取其中的一部分。这种情况称为“投影”。这类似于使用数据库

view
而不是
select * from table
。有几种解决方案,但我喜欢使用 DTO 作为接口的解决方案。让我们开始。我们创建 DTO 作为带有特定注释的接口

@NamedNativeQuery(name = "TestEntityDTO.getTestDate",
        query = "SELECT TEST_DATE FROM TEST_ENTITY",
        resultSetMapping = "Mapping.date")
@SqlResultSetMapping(name = "Mapping.TestEntityDTO",
        classes = @ConstructorResult(targetClass = TestEntityDTO.class,
                columns = {@ColumnResult(name = "date")}))
public interface TestEntityDTO {

    LocalDate getTestDate();

}

并修改我们的存储库

public interface TestRepositoryList extends CrudRepository<TestEntity, Long> {

    @Query(nativeQuery = true)
    List<TestEntityDTO> findBy();

}

注意我们将查询移至 DTO 注释 现在让我们写一个测试

    @Test
    void testFindByList() {
        testRepositoryList.save(new TestEntity(1L, LocalDate.now()));
        testRepositoryList.save(new TestEntity(2L, LocalDate.now()));
        testRepositoryList.findBy().forEach(
                e -> System.out.println(e.getTestDate())
        );
    }

结果是

2024-06-07
2024-06-07

您可以在 spring 文档和这篇好文章中阅读有关投影的更多信息 https://thorben-janssen.com/spring-data-jpa-dto-native-queries/

© www.soinside.com 2019 - 2024. All rights reserved.