【问题标题】:Java 8 Date Time api in JPAJPA 中的 Java 8 日期时间 API
【发布时间】:2014-11-08 05:15:34
【问题描述】:

在 jpa 中集成 Java 8 Date Time api 的最佳方式是什么?

我添加了转换器:

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

    @Override
    public Date convertToDatabaseColumn(LocalDate localDate) {
        return Date.valueOf(localDate);
    }

    @Override
    public LocalDate convertToEntityAttribute(Date date) {
        return date.toLocalDate();
    }
}

@Converter(autoApply = true)
public class LocalDateTimePersistenceConverter implements AttributeConverter<LocalDateTime, Timestamp> {
    @Override
    public Timestamp convertToDatabaseColumn(LocalDateTime entityValue) {
        return Timestamp.valueOf(entityValue);
    }

    @Override
    public LocalDateTime convertToEntityAttribute(Timestamp databaseValue) {
        return databaseValue.toLocalDateTime();
    }
}

一切似乎都很好,但我应该如何使用 JPQL 进行查询?我正在使用 Spring JPARepository,目标是选择日期与给定日期相同的所有实体,唯一的区别是它作为 LocalDateTime 保存在实体中。

所以:

public class Entity  {

    private LocalDateTime dateTime;

    ...
}

还有:

@Query("select case when (count(e) > 0) then true else false end from Entity e where e.dateTime = :date")
public boolean check(@Param("date") LocalDate date);

执行时它只会给我一个异常,这是正确的。

Caused by: java.lang.IllegalArgumentException: Parameter value [2014-01-01] did not match expected type [java.time.LocalDateTime (n/a)]

我尝试了很多方法,但似乎没有一个有效,这可能吗?

【问题讨论】:

  • 您的字段属于 LocalDateTime 类型。您的参数属于 LocalDate 类型。它应该是 LocalDateTime 类型。执行查询时会发生什么?
  • 是的,我明白了,我需要保存日期时间但按日期查询。
  • 那么为什么不使用date.atStartOfDay() 将您的LocalDate 转换为LocalDateTime?错误消息准确地告诉您参数的类型不正确,应该是 LocalDateTime 类型。
  • “最佳方式”取决于您的 JPA 实现。我使用的 JPA impl (DataNucleus JPA) 允许它开箱即用,无需特殊代码。你在用什么?
  • 我正在使用 spring-jpa 和休眠。还有一次,我知道为什么会有异常,我在问如何通过另一种方式使其工作。但看起来我需要考虑其他事情。

标签: spring hibernate jpa java-8 spring-data-jpa


【解决方案1】:

Hibernate 有一个扩展库,我相信 hibernate-java8,它本机支持许多时间类型。

您应该在编写转换器之前使用它。

在 hibernate 5.2 你不需要这个额外的库,它是核心的一部分。

【讨论】:

  • +1 用于提及 hibernate 5.2 将其作为默认设置。我正在使用 JPA2.1 和 hibernate-core 5.2 并且没有遇到这个问题。
【解决方案2】:

要查询时态字段,您应该在时态字段中使用@Temporal 注解,将转换器添加到 persistence.xml 并确保您使用的是 java.sql.Date、java.sql.Time 或 java.sql。转换器中的时间戳。 (有时我从错误的包中导入)

例如,这对我有用:

@Temporal(TemporalType.TIMESTAMP)
@Convert(converter = InstantPersistenceConverter.class)
private Instant StartInstant;
@Temporal(TemporalType.TIME)
@Convert(converter = LocalTimePersistenceConverter.class)
private LocalTime StartTime;

和我的即时转换器:

@Converter(autoApply = true)
public class InstantPersistenceConverter implements   AttributeConverter <Instant,java.sql.Timestamp>{
@Override
public java.sql.Timestamp convertToDatabaseColumn(Instant entityValue) {
    return java.sql.Timestamp.from(entityValue);
}

@Override
public Instant convertToEntityAttribute(java.sql.Timestamp databaseValue) {
    return databaseValue.toInstant();
}

}

【讨论】:

    【解决方案3】:

    您是否在“class”元素中的 persistence.xml 中添加了 LocalDatePersistenceConverter 和 LocalDateTimePersistenceConverter ?

    【讨论】:

      猜你喜欢
      • 2016-09-07
      • 2020-03-09
      • 2014-07-06
      • 2013-07-05
      • 1970-01-01
      • 2017-07-29
      • 2016-05-08
      • 2015-12-26
      相关资源
      最近更新 更多