spring-data-jpa не работает с Java 8 LocalTime

1

Механизм вывода запроса хранилища Spring Data (версия 1.8) не работает должным образом с Java 8 LocalTime. Может ли кто-нибудь сказать мне, если я ошибаюсь или это ошибка?

Я храню время начала в 10:00

LocalTime startingTime = LocalTime.of(10,0); myEntity.setHorai(startingTime); myEntityRepository.save(myEntity);

Затем я прошу всех сущностей, время начала которых больше 08:00:

LocalTime zeroEight = LocalTime.of(8, 0); List<MyEntity> ents = myEntityRepository.findByStartingTimeAfter(zeroEight);

Я вижу, что Hibernate (я использую Hibernate версии 4.3.7.Final) выполняет это:

Hibernate: select <all fields> from MyEntity m_ where m_.startingTime>? TRACE 2015-03-27 12:08:51,283 ohtype.descriptor.sql.BasicBinder: binding parameter [1] as [VARBINARY] - [08:00]

Таким образом, List должен содержать 1 элемент, но имеет 0 элементов. Если вместо findByStartingTimeAfter я использую findByStartingTimeBefore он возвращает 1 элемент, но я не уверен, что это потому, что я не понимаю, как работать до и после. Я пробовал с findByStartingTimeGreaterThan но терпит неудачу таким же образом.

Может быть, механизм вывода запроса не работает с Java 8 LocalTime?

Возможно, проблема в Hibernate, которая не сравнивает правильно данные VARBINARY (я вижу, что LocalTime хранится как BLOB, но он правильно хранится и извлекается как LocalTime)?

Я использую postgres 9.2, но я не думаю, что проблема связана с postgres.

Большое спасибо.

Теги:
java-8
hibernate
spring-data-jpa
spring-data

2 ответа

1
Лучший ответ

Ответ в этом вопросе. Hibernate еще не поддерживает классы java.time (это будет в версии 5.0). Поэтому он рассматривает LocalTime как экземпляр Serializable и просто хранит сериализованный экземпляр LocalTime в виде байтового массива в столбце varbinary. Таким образом, оператор > не имеет особого смысла в этом типе столбца и не будет сравнивать значения LocalTime в хронологическом порядке.

Вы можете определить свой собственный тип Hibernate или использовать jadira (который определяет этот настраиваемый тип для вас), чтобы сохранить значение LocalTime в соответствующем типе столбца.

  • 0
    Я подожду Hibernate 5. Спасибо.
  • 0
    Это не совсем правильно. В Spring Data JPA 1.8 поставляются конвертеры JPA 2.1, которые позволяют сохранять эти типы «из коробки» на имеющихся в настоящее время поставщиках персистентности. Смотрите мой ответ для более подробной информации.
Показать ещё 1 комментарий
1

Без дополнительной информации о сопоставлении Hibernate будет рассматривать даты JDK 8 как BLOB и, следовательно, больше не может применять какие-либо операции сравнения к этим полям.

Одним из решений этого является использование библиотеки пользовательских типов Jadira для настройки способа сопоставления этих типов в базе данных.

Если вы имеете дело только с не-временными зонами (например, LocalDate, LocalDateTime), самым простым способом является использование конвертеров JPA 2.1, поставляемых с Spring Data JPA 1.8. Просто убедитесь, что Jsr310JpaConverters - это список постоянных классов (либо путем сканирования соответствующего пакета, либо вручную перечисления этого класса в вашем persistence.xml), и эти конкретные типы даты и времени JDK 8 сопоставляются с Date прозрачно, чтобы любой постоянный провайдер сохранялся их сразу. Дополнительную информацию об этом можно найти в блоге, в котором сообщается о новых функциях в выпуске Spring Data Fowler.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню