最新的Spring Data/Hibernate在本机查询中不支持java.time.LocalDate?

wis*_*ame 5 spring-data jsr310 spring-data-jpa hibernate-5.x localdate

问题:使用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
}
Run Code Online (Sandbox Code Playgroud)

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

问题是在运行时,Spring Data存储库(其实现我无法控制,或者有没有办法?)返回java.sql.Datejava.time.LocalDate(澄清:返回类型似乎由Spring Data决定,java.sql.Date即使我将返回类型更改为是的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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

Jen*_*der 6

您似乎发现转换器之间存在差距。春季数据转换之间的开箱java.util.Datejava.time.LocalDate,但不会之间 java.time.LocalDate以及java.sql.Date和其他日期和时间相关类型的java.sql包。

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

另外,您可能要创建功能请求,并且如果要构建转换器供您使用,甚至可以提交拉取请求。


小智 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();
    }
Run Code Online (Sandbox Code Playgroud)

CAST告诉JPQL使用可用的Java日期\时间类型,而不是java.sql.Date