document the default behavior of time zone storage

This commit is contained in:
Gavin 2022-12-07 09:33:27 +01:00 committed by Gavin King
parent cc570da296
commit 6b1cbc0640
3 changed files with 96 additions and 33 deletions

View File

@ -22,7 +22,7 @@ import static java.lang.annotation.ElementType.METHOD;
* element collection value is of basic type. If the {@code TimeZoneStorage} annotation is not used,
* the {@link TimeZoneStorageType} has a default value determined by the dialect and by the
* configuration property {@value org.hibernate.cfg.AvailableSettings#TIMEZONE_DEFAULT_STORAGE}.
*
* <p>
* For example:
* <pre>
* {@code
@ -43,6 +43,8 @@ import static java.lang.annotation.ElementType.METHOD;
* @author Christian Beikov
* @author Steve Ebersole
* @author Andrea Boriero
*
* @see TimeZoneStorageType
* @see TimeZoneColumn
*
* @since 6.0

View File

@ -10,12 +10,49 @@ import org.hibernate.Incubating;
import org.hibernate.dialect.Dialect;
/**
* Describes the storage of timezone information for zoned datetime types.
* Describes the storage of timezone information for zoned datetime types,
* in particular, for the types {@link java.time.OffsetDateTime} and
* {@link java.time.ZonedDateTime}.
* <p>
* A default {@code TimeZoneStorageType} may be configured explicitly using
* {@value org.hibernate.cfg.AvailableSettings#TIMEZONE_DEFAULT_STORAGE}.
* Otherwise, the storage type may be overridden for a given field or
* property of an entity using the {@link TimeZoneStorage} annotation.
* <p>
* In choosing a {@code TimeZoneStorageType} we must consider whether a
* round trip to the database, writing and then reading a zoned datetime,
* preserves:
* <ul>
* <li>the {@linkplain java.time.OffsetDateTime#toInstant() instant}
* represented by the zoned datetime, and/or
* <li>the {@linkplain java.time.OffsetDateTime#getOffset() offset} or
* {@linkplain java.time.ZonedDateTime#getZone() zone} in which the
* instant is represented.
* </ul>
* We must also consider the physical representation of the zoned datetime
* in the database table.
* <p>
* The {@link #DEFAULT default strategy} guarantees that a round trip
* preserves the instant. Whether the zone or offset is preserved depends
* on whether the underlying database has a {@code timestamp with time zone}
* type which preserves offsets:
* <ul>
* <li>if the database does indeed have such an ANSI-compliant type, then
* both instant and zone or offset are preserved by round trips, but
* <li>if not, it's guaranteed that the physical representation is in UTC,
* so that datetimes retrieved from the database will be represented in
* UTC.
* </ul>
* When this default strategy is not appropriate, recommended alternatives
* are:
* <ul>
* <li>{@link #AUTO} or {@link #COLUMN}, which each guarantee that both
* instant and zone or offset are preserved by round trips on every
* platform, or
* <li>{@link #NORMALIZE_UTC}, which guarantees that only the instant is
* preserved, and that datetimes retrieved from the database will always
* be represented in UTC.
* </ul>
*
* @author Christian Beikov
* @author Steve Ebersole
@ -39,6 +76,9 @@ public enum TimeZoneStorageType {
/**
* Does not store the time zone, and instead normalizes
* timestamps to the JDBC timezone.
* <p>
* Provided for backward compatibility with older versions
* of Hibernate
*/
NORMALIZE,
/**
@ -59,6 +99,11 @@ public enum TimeZoneStorageType {
* {@link Dialect#getTimeZoneSupport()} is
* {@link org.hibernate.dialect.TimeZoneSupport#NATIVE},
* otherwise uses the {@link #COLUMN} strategy.
* <p>
* This option automatically picks an appropriate strategy
* for the database dialect which preserves both the instant
* represented by a zoned datetime type, and the offset or
* timezone.
*/
AUTO,
/**
@ -66,6 +111,12 @@ public enum TimeZoneStorageType {
* {@link Dialect#getTimeZoneSupport()} is
* {@link org.hibernate.dialect.TimeZoneSupport#NATIVE},
* otherwise uses the {@link #NORMALIZE_UTC} strategy.
* <p>
* This option automatically picks an appropriate strategy
* for the database dialect which preserves the instant
* represented by a zoned datetime type. It does not promise
* that the offset or timezone is preserved by a round trip
* to the database.
*
* @since 6.2
*/

View File

@ -2577,12 +2577,12 @@ public interface AvailableSettings {
* type is explicitly specified, a sensible
* {@link org.hibernate.dialect.Dialect#getPreferredSqlTypeCodeForBoolean()
* dialect-specific default type code} is used.
*
* <p>
* Can be overridden locally using {@link org.hibernate.annotations.JdbcType},
* {@link org.hibernate.annotations.JdbcTypeCode} and friends
*
* Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant field. E.g.
* {@code hibernate.type.preferred_boolean_jdbc_type=BIT}
* {@link org.hibernate.annotations.JdbcTypeCode}, and friends.
* <p>
* Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant
* field, for example, {@code hibernate.type.preferred_boolean_jdbc_type=BIT}.
*
* @since 6.0
*/
@ -2591,12 +2591,12 @@ public interface AvailableSettings {
/**
* The preferred JDBC type to use for storing {@link java.util.UUID} values.
*
* <p>
* Can be overridden locally using {@link org.hibernate.annotations.JdbcType},
* {@link org.hibernate.annotations.JdbcTypeCode} and friends
*
* Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant field. E.g.
* {@code hibernate.type.preferred_uuid_jdbc_type=CHAR}
* {@link org.hibernate.annotations.JdbcTypeCode}, and friends.
* <p>
* Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant
* field, for example, {@code hibernate.type.preferred_uuid_jdbc_type=CHAR}.
*
* @since 6.0
*/
@ -2604,14 +2604,14 @@ public interface AvailableSettings {
String PREFERRED_UUID_JDBC_TYPE = "hibernate.type.preferred_uuid_jdbc_type";
/**
* The preferred JDBC type to use for storing duration values. Falls back to
* The preferred JDBC type to use for storing duration values. Falls back to
* {@link org.hibernate.type.SqlTypes#INTERVAL_SECOND}.
*
* <p>
* Can be overridden locally using {@link org.hibernate.annotations.JdbcType},
* {@link org.hibernate.annotations.JdbcTypeCode} and friends
*
*Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant field. E.g.
* {@code hibernate.type.preferred_duration_jdbc_type=NUMERIC}
* {@link org.hibernate.annotations.JdbcTypeCode}, and friends.
* <p>
* Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant
* field, for example, {@code hibernate.type.preferred_duration_jdbc_type=NUMERIC}.
*
* @since 6.0
*/
@ -2620,13 +2620,14 @@ public interface AvailableSettings {
/**
* Specifies the preferred JDBC type for storing instant values. When no
* type is explicitly specified, {@link org.hibernate.type.SqlTypes#TIMESTAMP_UTC} is used.
*
* type is explicitly specified, {@link org.hibernate.type.SqlTypes#TIMESTAMP_UTC}
* is used.
* <p>
* Can be overridden locally using {@link org.hibernate.annotations.JdbcType},
* {@link org.hibernate.annotations.JdbcTypeCode} and friends
*
* Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant field. E.g.
* {@code hibernate.type.preferred_instant_jdbc_type=TIMESTAMP}
* {@link org.hibernate.annotations.JdbcTypeCode}, and friends.
* <p>
* Can also specify the name of the {@link org.hibernate.type.SqlTypes} constant
* field, for example, {@code hibernate.type.preferred_instant_jdbc_type=TIMESTAMP}.
*
* @since 6.0
*/
@ -2666,15 +2667,24 @@ public interface AvailableSettings {
String XML_FORMAT_MAPPER = "hibernate.type.xml_format_mapper";
/**
* Specifies the default strategy for storage of the timezone information
* for zoned datetime types:
* <ul>
* <li>{@link org.hibernate.annotations.TimeZoneStorageType#NORMALIZE}, or
* <li>{@link org.hibernate.annotations.TimeZoneStorageType#NATIVE}.
* </ul>
* The default is {@link org.hibernate.annotations.TimeZoneStorageType#NORMALIZE},
* meaning that timezone information is not stored by default, but timestamps are
* normalized to UTC instead.
* Specifies the default strategy for storage of the timezone information for the zoned
* datetime types {@link java.time.OffsetDateTime} and {@link java.time.ZonedDateTime}.
* The possible options for this setting are enumerated by
* {@link org.hibernate.annotations.TimeZoneStorageType}.
* <p>
* The default is {@link org.hibernate.annotations.TimeZoneStorageType#DEFAULT DEFAULT},
* which guarantees that the {@linkplain java.time.OffsetDateTime#toInstant() instant}
* represented by a zoned datetime type is preserved by a round trip to the database.
* It does <em>not</em> guarantee that the time zone or offset is preserved.
* <p>
* For backward compatibility with older versions of Hibernate, set this property to
* {@link org.hibernate.annotations.TimeZoneStorageType#NORMALIZE NORMALIZE}.
* <p>
* The default strategy specified using this setting may be overridden using the
* annotation {@link org.hibernate.annotations.TimeZoneStorage}.
*
* @see org.hibernate.annotations.TimeZoneStorageType
* @see org.hibernate.annotations.TimeZoneStorage
*
* @since 6.0
*/