mirror of
https://github.com/google/nomulus.git
synced 2025-06-19 19:00:46 +02:00
Implement UpdateAutoTimestampConverter (#298)
* Implement a JPA-based converter for UpdateAutoTimestamp, allowing us to persist instances of this class.
This commit is contained in:
parent
6cfcaa59b9
commit
b299eae86b
2 changed files with 148 additions and 0 deletions
|
@ -0,0 +1,46 @@
|
||||||
|
// 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 static google.registry.model.transaction.TransactionManagerFactory.jpaTm;
|
||||||
|
|
||||||
|
import google.registry.model.UpdateAutoTimestamp;
|
||||||
|
import google.registry.util.DateTimeUtils;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.persistence.AttributeConverter;
|
||||||
|
import javax.persistence.Converter;
|
||||||
|
|
||||||
|
/** JPA converter for storing/retrieving UpdateAutoTimestamp objects. */
|
||||||
|
@Converter
|
||||||
|
public class UpdateAutoTimestampConverter
|
||||||
|
implements AttributeConverter<UpdateAutoTimestamp, Timestamp> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timestamp convertToDatabaseColumn(UpdateAutoTimestamp entity) {
|
||||||
|
return Timestamp.from(DateTimeUtils.toZonedDateTime(jpaTm().getTransactionTime()).toInstant());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public UpdateAutoTimestamp convertToEntityAttribute(@Nullable Timestamp columnValue) {
|
||||||
|
if (columnValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ZonedDateTime zdt = ZonedDateTime.ofInstant(columnValue.toInstant(), ZoneOffset.UTC);
|
||||||
|
return UpdateAutoTimestamp.create(DateTimeUtils.toJodaDateTime(zdt));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
// 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 static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static google.registry.model.transaction.TransactionManagerFactory.jpaTm;
|
||||||
|
|
||||||
|
import google.registry.model.ImmutableObject;
|
||||||
|
import google.registry.model.UpdateAutoTimestamp;
|
||||||
|
import google.registry.model.transaction.JpaTransactionManagerRule;
|
||||||
|
import javax.persistence.Convert;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
import org.testcontainers.containers.PostgreSQLContainer;
|
||||||
|
|
||||||
|
@RunWith(JUnit4.class)
|
||||||
|
public class UpdateAutoTimestampConverterTest {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static PostgreSQLContainer postgres =
|
||||||
|
new PostgreSQLContainer()
|
||||||
|
.withDatabaseName("postgres")
|
||||||
|
.withUsername("postgres")
|
||||||
|
.withPassword("domain-registry");
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final JpaTransactionManagerRule jpaTmRule =
|
||||||
|
new JpaTransactionManagerRule.Builder()
|
||||||
|
.withEntityClass(TestEntity.class)
|
||||||
|
.withProperty(Environment.HBM2DDL_AUTO, "update")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public UpdateAutoTimestampConverterTest() {}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTypeConversion() {
|
||||||
|
TestEntity ent = new TestEntity("myinst", null);
|
||||||
|
|
||||||
|
jpaTm().transact(() -> jpaTm().getEntityManager().persist(ent));
|
||||||
|
|
||||||
|
TestEntity result =
|
||||||
|
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "myinst"));
|
||||||
|
|
||||||
|
assertThat(result.name).isEqualTo("myinst");
|
||||||
|
assertThat(result.uat.getTimestamp()).isEqualTo(jpaTmRule.getTxnClock().nowUtc());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeChangesOnSubsequentTransactions() {
|
||||||
|
TestEntity ent1 = new TestEntity("myinst1", null);
|
||||||
|
|
||||||
|
jpaTm().transact(() -> jpaTm().getEntityManager().persist(ent1));
|
||||||
|
|
||||||
|
TestEntity result1 =
|
||||||
|
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "myinst1"));
|
||||||
|
|
||||||
|
jpaTmRule.getTxnClock().advanceOneMilli();
|
||||||
|
|
||||||
|
TestEntity ent2 = new TestEntity("myinst2", result1.uat);
|
||||||
|
|
||||||
|
jpaTm().transact(() -> jpaTm().getEntityManager().persist(ent2));
|
||||||
|
|
||||||
|
TestEntity result2 =
|
||||||
|
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "myinst2"));
|
||||||
|
|
||||||
|
assertThat(result1.uat.getTimestamp()).isNotEqualTo(result2.uat.getTimestamp());
|
||||||
|
assertThat(result2.uat.getTimestamp()).isEqualTo(jpaTmRule.getTxnClock().nowUtc());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
|
||||||
|
public static class TestEntity extends ImmutableObject {
|
||||||
|
|
||||||
|
@Id String name;
|
||||||
|
|
||||||
|
@Convert(converter = UpdateAutoTimestampConverter.class)
|
||||||
|
UpdateAutoTimestamp uat;
|
||||||
|
|
||||||
|
public TestEntity() {}
|
||||||
|
|
||||||
|
public TestEntity(String name, UpdateAutoTimestamp uat) {
|
||||||
|
this.name = name;
|
||||||
|
this.uat = uat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue