2017-01-18 2 views
4

У меня есть объект, который расширяет класс аудита сущностей с именем AbstractAuditingEntity, в котором один из поля являетсяНе удалось сохранить java.time.ZonedDateTime используя спящий режим PostgresSQL

@CreatedDate 
@Column(name = "created_date", nullable = false) 
@JsonIgnore 
private ZonedDateTime createdDate 

Над полем имеет отображение в поле базы данных с именем "created_date" с type "timestamp without time zone".

Но в момент сохранения этой сущности PostgresSQL бросает ошибку следующим образом:

Caused by: org.postgresql.util.PSQLException: ERROR: column "created_date" is of type timestamp without time zone but expression is of type bytea 
    Hint: You will need to rewrite or cast the expression. 

Я посмотрел на ту же ошибку & нашел решение здесь: Postgresql UUID supported by Hibernate?

Но решение для java.util.UUID в растворе предлагается добавить аннотацию @Type(type="pg-uuid") в поле с типом UUID.

Есть ли такое готовое к употреблению значение типа pg-uuid для ZonedDateTime? Любая ссылка ссылки для разных значений констант hibernate @Type аннотация?

Или я должен написать собственный класс десериализатора? Как написать такой класс десериализатора любой ссылочной ссылки?

PostgresSQL Version : 9.6, 
<liquibase-hibernate5.version>3.6</liquibase-hibernate5.version> 
+0

Можете ли вы включить отладочные журналы на 'org.hibernate.type' в своем журнале? Вы должны найти что-то подобное, если типы зарегистрированы http://pastebin.com/t2xh5UvM и должны работать. – coladict

+0

До Hibernate 5.2 обработка Java-8 классов времени появилась в дополнительном модуле. – coladict

ответ

3

Для Hibernate 5.2 он должен просто работать из коробки.

Для 5.0 вы можете добавить зависимость, чтобы поддержать его:

<dependency> 
    <groupId>org.hibernate</groupId> 
    <artifactId>hibernate-java8</artifactId> 
    <version>${hibernate.version}</version> 
</dependency> 

Для 4.3 вы можете использовать JPA 2.1 нейтрализатор:

@Converter 
public class TimestampConverter implements AttributeConverter<ZonedDateTime, Timestamp> { 
    @Override 
    public Timestamp convertToDatabaseColumn(ZonedDateTime zonedTime) { 
     if (zonedTime == null) { 
      return null; 
     } 
     return new Timestamp(zonedTime.toInstant().toEpochMilli()); 
    } 

    @Override 
    public ZonedDateTime convertToEntityAttribute(Timestamp localTime) { 
     if (localTime == null) { 
      return null; 
     } 
     return ZonedDateTime.ofInstant(Instant.ofEpochMilli(localTime.getTime()), ZoneId.systemDefault()); 
    } 
} 

Затем аннотировать атрибут с @Convert:

@Convert(converter = TimestampConverter.class) 
private ZonedDateTime createdDate; 

Отметьте, что ваш столбец базы данных TIMESTAMP. Это действительно должно быть TIMESTAMP WITH TIME ZONE, особенно если ваш часовой пояс вашего клиента имеет переход на летнее время.

+0

Обратите внимание, что вы теряете информацию о часовом поясе в своем решении для 4.3. – jannis

+0

Postgres не хранит информацию о смещении в 'TIMESTAMP' или' TIMESTAMP WITH TIME ZONE'. – teppic

Смежные вопросы