如何将PostgreSQL的"time without time zone"映射到JPA/Hibernate实体?
针对PostgreSQL的time without time zone类型映射到JPA/Hibernate实体的问题,我给你整理了几种靠谱的解决方式,结合你给出的代码片段,咱们一步步来优化:
方案1:直接使用Hibernate内置类型(最推荐)
从Hibernate 5.2版本开始,已经原生支持Java 8的时间API类型,包括LocalTime。只要你的PostgreSQL字段确实是time without time zone,直接这么定义实体字段就够了,完全不用自己写转换器:
@Column(name = "send_time", columnDefinition = "time without time zone not null") private LocalTime sendTime;
⚠️ 这里要提个醒:你代码里写的columnDefinition是timestamp without time zone,但字段类型用了LocalTime,这其实不匹配——timestamp without time zone对应的Java类型应该是LocalDateTime,如果你的数据库字段是时间戳类型,记得把实体字段改成LocalDateTime哦。
方案2:自定义AttributeConverter(兼容旧版Hibernate)
如果你的Hibernate版本比较老,不支持原生Java 8时间类型,那可以自定义转换器,但你原来的代码有个小问题:set方法的名字应该是setSendTime而不是setLocalTime,不然JPA没法正确识别。修正后的完整代码如下:
@Getter @Setter @Entity public class YourEntity { @Column(name = "send_time", columnDefinition = "time without time zone not null") @Convert(converter = LocalTimeConverter.class) private LocalTime sendTime; @Converter(autoApply = true) public static class LocalTimeConverter implements AttributeConverter<LocalTime, Time> { @Override public Time convertToDatabaseColumn(LocalTime localTime) { return localTime != null ? Time.valueOf(localTime) : null; } @Override public LocalTime convertToEntityAttribute(Time time) { return time != null ? time.toLocalTime() : null; } } }
几个关键点:
- 转换器要实现
AttributeConverter<LocalTime, Time>,因为JDBC中对应PostgreSQLtime without time zone的标准类型是java.sql.Time - 加上
autoApply = true后,所有实体中的LocalTime类型字段都会自动应用这个转换器,不用每个字段都加@Convert注解
方案3:使用Hibernate的@Type注解
还有一种方式是用Hibernate的@Type注解明确指定映射类型,代码如下:
@Column(name = "send_time", columnDefinition = "time without time zone not null") @Type(type = "org.hibernate.type.LocalTimeType") private LocalTime sendTime;
这个方案和方案1本质上是一样的,都是用Hibernate原生支持的类型,适合需要显式指定类型的场景。
内容的提问来源于stack exchange,提问作者Himanshu Yadav
相关产品推荐
相关产品推荐

