当前位置:  开发笔记 > 编程语言 > 正文

无法使用hibernate PostgreSQL存储java.time.ZonedDateTime

如何解决《无法使用hibernatePostgreSQL存储java.time.ZonedDateTime》经验,为你挑选了1个好方法。

我有一个实体,它扩展了一个名为AbstractAuditingEntity的审计实体类,其中一个字段是

@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.

我在这里寻找相同的错误并找到了解决方案:Hibernate支持的Postgresql UUID?

但解决方案是java.util.UUID,在解决方案中,建议@Type(type="pg-uuid")在具有UUID类型的字段上添加注释 .

有没有像任何这样的愿意使用的类型值pg-uuidZonedDateTime?hibernate @Type注释的不同值常量的任何引用链接?

或者我应该写一个自定义反序列化器类?如何编写这样的反序列化类任何引用链接?

PostgresSQL Version  : 9.6,
3.6

teppic.. 5

对于Hibernate 5.2,它应该开箱即用。

对于5.0,您可以添加一个依赖项来支持它:


    org.hibernate
    hibernate-java8
    ${hibernate.version}

对于4.3,可以使用JPA 2.1转换器:

@Converter
public class TimestampConverter implements AttributeConverter {
    @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,特别是如果您的客户所在时区具有夏令时更改。



1> teppic..:

对于Hibernate 5.2,它应该开箱即用。

对于5.0,您可以添加一个依赖项来支持它:


    org.hibernate
    hibernate-java8
    ${hibernate.version}

对于4.3,可以使用JPA 2.1转换器:

@Converter
public class TimestampConverter implements AttributeConverter {
    @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,特别是如果您的客户所在时区具有夏令时更改。

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有