8

问题:带有 Spring Data 返回日期的本机查询返回 java.sql.Date 而不是 java.time.LocalDate,尽管进行了设置。

上下文:一个带有 Spring Boot 2.0.0.M5(最新)、Hibernate 5.2.11、Hibernate-Java8 5.2.12(只要它在类路径上就支持 JSR310 类)的新项目。

下面的匿名示例(该应用程序与生日无关):

public interface BirthdayRepository<T, ID extends Serializable> extends Repository<T, ID> {
    @Query(value = "select day from birthdays", nativeQuery = true)
    Iterable<java.sql.Date> getBirthdays(); //the return type should ideally be java.time.LocalDate
}

在数据库(SQL Server)中,day 字段为 DATE,值类似于 2017-10-24。

问题是在运行时,Spring Data 存储库(我无法控制其实现,或者有办法?)没有返回java.sql.Datejava.time.LocalDate(澄清:返回类型似乎由 Spring Data 决定,java.sql.Date即使我将返回类型更改为be java.time.LocalDate,这就是我开始的方式)。

没有办法LocalDate直接获取吗?我可以稍后转换它,但是(1)效率低下,(2)存储库方法必须返回旧的日期/时间类,这是我想避免的。我阅读了 Spring Data文档,但对此一无所知。

编辑:对于任何有同样问题的人,下面是解决方案,Jens 建议的转换器。

public class LocalDateTypeConverter {

    @Converter(autoApply = true)
    public static class LocalDateConverter implements AttributeConverter<LocalDate, Date> {

        @Nullable
        @Override
        public Date convertToDatabaseColumn(LocalDate date) {
            return date == null ? null : new Date(LocalDateToDateConverter.INSTANCE.convert(date).getTime());
        }

        @Nullable
        @Override
        public LocalDate convertToEntityAttribute(Date date) {
            return date == null ? null : DateToLocalDateConverter.INSTANCE.convert(date);
        }
    }
4

2 回答 2

7

看起来您在转换器中发现了一个缺口。Spring Data 开箱即用地转换包中的java.util.Dateandjava.time.LocalDate而不是 between java.time.LocalDateandjava.sql.Date和其他与日期和时间相关的类型java.sql

您可以创建自己的转换器来做到这一点。您可以使用Jsr310JpaConverters作为模板。

此外,您可能想要创建一个功能请求,如果您构建一个供您使用的转换器,您甚至可以提交一个拉取请求。

于 2017-10-25T14:31:04.817 回答
5

我知道这是一个较老的问题,但我对这个问题的解决方案不需要自定义转换器。

    public interface BirthdayRepository<T, ID extends Serializable> extends Repository<T, ID> {
      @Query(value = "select cast(day as date) from birthdays", nativeQuery = true)
      Iterable<java.time.LocalDate> getBirthdays();
    }

CAST告诉 JPQL 使用可用的java date\time 类型而不是 java.sql.Date

于 2019-09-19T20:30:31.797 回答