简体   繁体   English

使用休眠PostgreSQL无法存储java.time.ZonedDateTime

[英]Failed to store java.time.ZonedDateTime using hibernate PostgreSQL

I have an entity which extends an auditing entity class named AbstractAuditingEntity in which one of the field is 我有一个实体,该实体扩展了名为AbstractAuditingEntity的审核实体类,其中一个字段是

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

Above field has mapping to database field named "created_date" with type "timestamp without time zone" . 上面的字段已映射到名为"created_date"数据库字段,其类型为"timestamp without time zone"

But at the time of saving this entity PostgresSQL throws error as follows : 但是在保存此实体时,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.

I looked for the same error & found solution here : Postgresql UUID supported by Hibernate? 我在寻找相同的错误并在此处找到解决方案: Hibernate支持的Postgresql UUID吗?

But the solution is for java.util.UUID , in solution it is suggested to add annotation @Type(type="pg-uuid") on a field with UUID type. 但是解决方案是针对java.util.UUID ,在解决方案中,建议在具有UUID类型的字段上添加注释@Type(type="pg-uuid")

Is there any such a ready-to-use type value like pg-uuid for ZonedDateTime ? ZonedDateTime是否有像pg-uuid这样的随时可用的类型值? Any reference link for the different values constants of hibernate @Type annotation ? 休眠@Type注释的不同值常量的任何引用链接吗?

Or am supposed to write a custom deserializer class ? 还是应该编写一个自定义反序列化器类? How to write such deserializer class any reference link ? 怎么写这样的反序列化类任何参考链接?

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

For Hibernate 5.2 it should just work out of the box. 对于Hibernate 5.2,它应该开箱即用。

For 5.0 you can add a dependency to support it: 对于5.0,您可以添加一个依赖项来支持它:

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

For 4.3 you can use a JPA 2.1 converter: 对于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());
    }
}

Then annotate your attribute with @Convert : 然后用@Convert注释属性:

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

I note that your database column is TIMESTAMP . 我注意到您的数据库列是TIMESTAMP It should really be TIMESTAMP WITH TIME ZONE , especially if your client time zone has daylight savings changes. 确实应该是TIMESTAMP WITH TIME ZONE ,尤其是在您的客户所在时区具有夏令时更改的情况下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM