The most appropriate solution to solve the problem is to use an AttributeConverter to convert Java 8 ZonedDateTime objects to ZonedDateTime objects so that they can be mapped to the PostgreSQL type timestamp without time zone .
The reason you need AttributeConverter is because Java 8 / Joda date time types are not yet compatible with JPA .
AttributeConverter as follows:
@Converter(autoApply = true) public class ZonedDateTimeAttributeConverter implements AttributeConverter<ZonedDateTime, Timestamp> { @Override public Timestamp convertToDatabaseColumn(ZonedDateTime zonedDateTime) { return (zonedDateTime == null ? null : Timestamp.valueOf(zonedDateTime.toLocalDateTime())); } @Override public ZonedDateTime convertToEntityAttribute(Timestamp sqlTimestamp) { return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime().atZone(ZoneId.of("UTC"))); } }
This allows me to read database timestamps that do not have timezone information in the form of ZonedDateTime objects that have a UTC timezone. This way, I keep the exact time that can be seen on db , regardless of the time zone in which my application runs .
Since toLocalDateTime() also applies the default time zone change, this AttributeConverter basically overrides the conversion used by the JDBC driver.
Do you really need to use timestamp without timezone ?
The reality is that if you store time date information in the time zone (even if it is UTC), the type timestamp without timezone PostgreSQL is the wrong choice. The correct data type to use would be timestamp with timezone , which includes time zone information. Read more about this topic here .
However, if for some reason you should use timestamp without timezone , I think the ZonedDateTime approach ZonedDateTime is a reliable and consistent solution.
Do you also serialize ZonedDateTime to JSON?
Then you are probably curious that you need at least version 2.6.0 jackson-datatype-jsr310 for serialization. More on this in this answer .
source share