You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot JPA查询多行LocalDate失败,单行正常:无可用转换器

Spring Boot 3.3.0中JPA多行LocalDate查询失败问题

JPA 2.2原生支持Java 8的LocalDate类型,但在Spring Boot 3.3.0版本下,使用原生SQL查询单行LocalDate数据时正常,查询多行却无法完成类型转换,抛出转换器找不到的异常。

错误日志

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)

相关代码

TestEntity.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和Getter方法
}

单行查询仓库(正常运行)

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

多行查询仓库(执行失败)

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

测试代码

// 正常运行的单行查询测试
@Test
void testFindBySingle() throws InterruptedException {
    testRepository.save(new TestEntity(1L, LocalDate.now()));
    log.info(String.valueOf(testRepository.findBy()));
}

// 执行失败的多行查询测试
@Test
void testFindByList() {
    testRepositoryList.save(new TestEntity(1L, LocalDate.now()));
    testRepositoryList.save(new TestEntity(2L, LocalDate.now()));
    log.info(String.valueOf(testRepositoryList.findBy()));
}

解决方案

方案1:改用JPQL查询

放弃原生SQL,使用JPQL让JPA自动处理类型映射,这是最推荐的方式:

public interface TestRepositoryList extends CrudRepository<TestEntity, Long> {
    @Query("SELECT t.testDate FROM TestEntity t")
    List<LocalDate> findBy();
}

方案2:注册自定义类型转换器

如果必须使用原生SQL,可以添加自定义转换器处理java.sql.Date到LocalDate的转换:

  1. 创建转换器类:
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import java.sql.Date;
import java.time.LocalDate;

@Component
public class SqlDateToLocalDateConverter implements Converter<Date, LocalDate> {
    @Override
    public LocalDate convert(Date source) {
        return source != null ? source.toLocalDate() : null;
    }
}
  1. 配置转换器(若Spring未自动扫描到,可手动注册):
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new SqlDateToLocalDateConverter());
    }
}

方案3:数据库端显式转换(依赖数据库类型)

针对特定数据库,在原生SQL中显式转换日期格式,例如MySQL:

@Query(value = "SELECT CAST(TEST_DATE AS DATE) FROM TEST_ENTITY", nativeQuery = true)
List<LocalDate> findBy();

内容的提问来源于stack exchange,提问作者Justus5324

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:35:00