-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement support for hibernate timestamp columns with timezone (#728)
* Implement support for hibernate timestamp columns with the 'with time zone' suffix. * Add unit test for timestamp columns with or without timezones * Fix timezone handling for timestamp columns with an explicit columnDefinition
- Loading branch information
1 parent
2a58b82
commit 3126d8c
Showing
3 changed files
with
156 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.example.timezone; | ||
|
||
import jakarta.persistence.*; | ||
|
||
import java.time.Instant; | ||
import java.time.LocalDateTime; | ||
|
||
@Entity | ||
public class Item { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.SEQUENCE) | ||
private long id; | ||
|
||
@Column | ||
private Instant timestamp1; | ||
|
||
@Column | ||
private LocalDateTime timestamp2; | ||
|
||
@Column(columnDefinition = "timestamp") | ||
private Instant timestamp3; | ||
|
||
@Column(columnDefinition = "TIMESTAMP WITH TIME ZONE") | ||
private LocalDateTime timestamp4; | ||
|
||
public long getId() { | ||
return id; | ||
} | ||
|
||
public void setId(long id) { | ||
this.id = id; | ||
} | ||
|
||
public Instant getTimestamp1() { | ||
return timestamp1; | ||
} | ||
|
||
public void setTimestamp1(Instant timestamp1) { | ||
this.timestamp1 = timestamp1; | ||
} | ||
|
||
public LocalDateTime getTimestamp2() { | ||
return timestamp2; | ||
} | ||
|
||
public void setTimestamp2(LocalDateTime timestamp2) { | ||
this.timestamp2 = timestamp2; | ||
} | ||
|
||
public Instant getTimestamp3() { | ||
return timestamp3; | ||
} | ||
|
||
public void setTimestamp3(Instant timestamp3) { | ||
this.timestamp3 = timestamp3; | ||
} | ||
|
||
public LocalDateTime getTimestamp4() { | ||
return timestamp4; | ||
} | ||
|
||
public void setTimestamp4(LocalDateTime timestamp4) { | ||
this.timestamp4 = timestamp4; | ||
} | ||
|
||
} |
66 changes: 66 additions & 0 deletions
66
src/test/java/liquibase/ext/hibernate/snapshot/TimezoneSnapshotTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package liquibase.ext.hibernate.snapshot; | ||
|
||
import liquibase.CatalogAndSchema; | ||
import liquibase.database.Database; | ||
import liquibase.integration.commandline.CommandLineUtils; | ||
import liquibase.resource.ClassLoaderResourceAccessor; | ||
import liquibase.snapshot.DatabaseSnapshot; | ||
import liquibase.snapshot.SnapshotControl; | ||
import liquibase.snapshot.SnapshotGeneratorFactory; | ||
import liquibase.structure.DatabaseObject; | ||
import liquibase.structure.core.Column; | ||
import liquibase.structure.core.DataType; | ||
import org.hamcrest.FeatureMatcher; | ||
import org.hamcrest.Matcher; | ||
import org.junit.Test; | ||
|
||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.*; | ||
|
||
public class TimezoneSnapshotTest { | ||
|
||
@Test | ||
public void testTimezoneColumns() throws Exception { | ||
Database database = CommandLineUtils.createDatabaseObject(new ClassLoaderResourceAccessor(this.getClass().getClassLoader()), "hibernate:spring:com.example.timezone?dialect=org.hibernate.dialect.H2Dialect", null, null, null, null, null, false, false, null, null, null, null, null, null, null); | ||
|
||
DatabaseSnapshot snapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(CatalogAndSchema.DEFAULT, database, new SnapshotControl(database)); | ||
|
||
assertThat( | ||
snapshot.get(Column.class), | ||
hasItems( | ||
// Instant column should result in 'timestamp with timezone' type | ||
allOf( | ||
hasProperty("name", equalTo("timestamp1")), | ||
hasDatabaseAttribute("type", DataType.class, hasProperty("typeName", equalTo("timestamp with timezone"))) | ||
), | ||
// LocalDateTime column should result in 'timestamp' type | ||
allOf( | ||
hasProperty("name", equalTo("timestamp2")), | ||
hasDatabaseAttribute("type", DataType.class, hasProperty("typeName", equalTo("timestamp"))) | ||
), | ||
// Instant column with explicit definition 'timestamp' should result in 'timestamp' type | ||
allOf( | ||
hasProperty("name", equalTo("timestamp3")), | ||
hasDatabaseAttribute("type", DataType.class, hasProperty("typeName", equalTo("timestamp"))) | ||
), | ||
// LocalDateTime Colum with explicit definition 'TIMESTAMP WITH TIME ZONE' should result in 'TIMESTAMP with timezone' type | ||
allOf( | ||
hasProperty("name", equalTo("timestamp4")), | ||
hasDatabaseAttribute("type", DataType.class, hasProperty("typeName", equalToIgnoringCase("timestamp with timezone"))) | ||
) | ||
) | ||
); | ||
} | ||
|
||
private static <T> FeatureMatcher<DatabaseObject, T> hasDatabaseAttribute(String attribute, Class<T> type, Matcher<T> matcher) { | ||
return new FeatureMatcher<>(matcher, attribute, attribute) { | ||
|
||
@Override | ||
protected T featureValueOf(DatabaseObject databaseObject) { | ||
return databaseObject.getAttribute(attribute, type); | ||
} | ||
|
||
}; | ||
} | ||
|
||
} |