Implement ZonedDateTimeConverter (#287)

* Implement ZonedDateTimeConverter

* Use dedicated TestEntity for ZonedDateTimeConverterTest
This commit is contained in:
Shicong Huang
2019-10-08 16:46:07 -04:00
committed by GitHub
parent 5dc058ec99
commit 022f397cd9
6 changed files with 184 additions and 1 deletions
@@ -61,6 +61,8 @@ public class PersistenceModule {
// SessionFactory is created. Setting it to 'none' to turn off the feature.
properties.put(Environment.HBM2DDL_AUTO, "none");
// Hibernate converts any date to this timezone when writing to the database.
properties.put(Environment.JDBC_TIME_ZONE, "UTC");
properties.put(
Environment.PHYSICAL_NAMING_STRATEGY, NomulusNamingStrategy.class.getCanonicalName());
@@ -0,0 +1,48 @@
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence;
import java.sql.Timestamp;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import javax.annotation.Nullable;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
/**
* JPA converter to for storing/retrieving {@link ZonedDateTime} objects.
*
* <p>Hibernate provides a default converter for {@link ZonedDateTime}, but it converts timestamp to
* a non-normalized format, e.g., 2019-09-01T01:01:01Z will be converted to
* 2019-09-01T01:01:01Z[UTC]. This converter solves that problem by explicitly calling {@link
* ZoneId#normalized()} to normalize the zone id.
*/
@Converter(autoApply = true)
public class ZonedDateTimeConverter implements AttributeConverter<ZonedDateTime, Timestamp> {
@Override
@Nullable
public Timestamp convertToDatabaseColumn(@Nullable ZonedDateTime attribute) {
return attribute == null ? null : Timestamp.from(attribute.toInstant());
}
@Override
@Nullable
public ZonedDateTime convertToEntityAttribute(@Nullable Timestamp dbData) {
return dbData == null
? null
: ZonedDateTime.ofInstant(dbData.toInstant(), ZoneId.of("UTC").normalized());
}
}
@@ -31,6 +31,7 @@ import google.registry.persistence.CreateAutoTimestampConverter;
import google.registry.persistence.NomulusNamingStrategy;
import google.registry.persistence.NomulusPostgreSQLDialect;
import google.registry.persistence.UpdateAutoTimestampConverter;
import google.registry.persistence.ZonedDateTimeConverter;
import google.registry.schema.domain.RegistryLock;
import google.registry.schema.tld.PremiumList;
import google.registry.schema.tmch.ClaimsList;
@@ -74,7 +75,8 @@ public class GenerateSqlSchemaCommand implements Command {
RegistryLock.class,
TransferData.class,
Trid.class,
UpdateAutoTimestampConverter.class);
UpdateAutoTimestampConverter.class,
ZonedDateTimeConverter.class);
@VisibleForTesting
public static final String DB_OPTIONS_CLASH =
@@ -35,6 +35,7 @@
<!-- Customized type converters -->
<class>google.registry.persistence.CreateAutoTimestampConverter</class>
<class>google.registry.persistence.UpdateAutoTimestampConverter</class>
<class>google.registry.persistence.ZonedDateTimeConverter</class>
<!-- TODO(weiminyu): check out application-layer validation. -->
<validation-mode>NONE</validation-mode>