revise new doc section
This commit is contained in:
parent
06961d7dbe
commit
632485f8b1
|
@ -851,24 +851,25 @@ Dates and times should always be represented using the types defined in `java.ti
|
||||||
====
|
====
|
||||||
Never use the legacy types `java.sql.Date`, `java.sql.Time`, `java.sql.Timestamp`, or `java.util.Date`.
|
Never use the legacy types `java.sql.Date`, `java.sql.Time`, `java.sql.Timestamp`, or `java.util.Date`.
|
||||||
At our urging, support for these types has even been https://in.relation.to/2024/04/22/stop-using-date/[officially deprecated in JPA 3.2].
|
At our urging, support for these types has even been https://in.relation.to/2024/04/22/stop-using-date/[officially deprecated in JPA 3.2].
|
||||||
Eventually, we hope to completely remove support for these types.
|
Eventually, we hope to completely remove support for these types from the JPA spec and from Hibernate.
|
||||||
====
|
====
|
||||||
|
|
||||||
Some of the types in `java.time` map naturally to an ANSI SQL column type.
|
Some of the types in `java.time` map naturally to an ANSI SQL column type.
|
||||||
A source of confusion is that some databases still don't follow the ANSI standard naming here.
|
A source of confusion is that some databases still don't follow the ANSI standard naming here.
|
||||||
Also, as you're probably aware, the `DATE` type on Oracle is not an ANSI SQL `DATE`.
|
Also, as you're probably aware, the `DATE` type on Oracle is not an ANSI SQL `DATE`.
|
||||||
|
In fact, Oracle doesn't have `DATE` or `TIME` types--every date or time must be stored as a timestamp.
|
||||||
|
|
||||||
.Type mappings from `java.time` to ANSI SQL
|
.Type mappings from `java.time` to ANSI SQL
|
||||||
|====
|
|====
|
||||||
| `java.time` class | ANSI SQL type | MySQL | SQL Server
|
| `java.time` class | ANSI SQL type | MySQL | SQL Server | Oracle
|
||||||
|
|
||||||
| `LocalDate` | `DATE` | `DATE` | `DATE`
|
| `LocalDate` | `DATE` | `DATE` | `DATE` | `DATE` 💀
|
||||||
| `LocalTime` | `TIME` | `TIME` | `TIME`
|
| `LocalTime` | `TIME` | `TIME` | `TIME` | `TIMESTAMP` 💀
|
||||||
| `LocalDateTime` | `TIMSTAMP` | `DATETIME` | `DATETIME2`
|
| `LocalDateTime` | `TIMSTAMP` | `DATETIME` | `DATETIME2` | `TIMESTAMP`
|
||||||
| `OffsetDateTime` | `TIMESTAMP WITH TIME ZONE` | `TIMESTAMP` 💀 | `DATETIMEOFFSET`
|
| `OffsetDateTime`, `ZonedDateTime` | `TIMESTAMP WITH TIME ZONE` | `TIMESTAMP` 🙄 | `DATETIMEOFFSET` | `TIMESTAMP WITH TIME ZONE`
|
||||||
|====
|
|====
|
||||||
|
|
||||||
On the other hand, there are no perfectly natural mappings for `Instant` and `Duration`.
|
On the other hand, there are no perfectly natural mappings for `Instant` and `Duration` on must databases.
|
||||||
By default:
|
By default:
|
||||||
|
|
||||||
- `Duration` is mapped to a column of type `NUMERIC(21)` holding the length of the duration in nanoseconds, and
|
- `Duration` is mapped to a column of type `NUMERIC(21)` holding the length of the duration in nanoseconds, and
|
||||||
|
@ -876,19 +877,21 @@ By default:
|
||||||
|
|
||||||
Fortunately, these mappings can be modified by specifying the `JdbcType`.
|
Fortunately, these mappings can be modified by specifying the `JdbcType`.
|
||||||
|
|
||||||
For example, if we wanted to store an `Instant` using `TIMESTAMP WITH TIME ZONE` (`TIMESTAMP` on MySQL) instead of `TIMESTAMP`, then we could annotated the field:
|
For example, if we wanted to store an `Instant` using `TIMESTAMP WITH TIME ZONE` (`TIMESTAMP` on MySQL) instead of `TIMESTAMP`, then we could annotate the field:
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
// store the Instant as a TIMESTAMP WITH TIME ZONE, instead of as a TIMESTAMP
|
||||||
@JdbcTypeCode(SqlTypes.TIMESTAMP_WITH_TIMEZONE)
|
@JdbcTypeCode(SqlTypes.TIMESTAMP_WITH_TIMEZONE)
|
||||||
Instant instant;
|
Instant instant;
|
||||||
----
|
----
|
||||||
|
|
||||||
Alternatively, we could set the property `hibernate.type.preferred_instant_jdbc_type`:
|
Alternatively, we could set the configuration property `hibernate.type.preferred_instant_jdbc_type`:
|
||||||
|
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
// store field of type Instant as TIMESTAMP WITH TIME ZONE, instead of as a TIMESTAMP
|
||||||
config.setProperty(MappingSettings.PREFERRED_INSTANT_JDBC_TYPE, SqlTypes.TIMESTAMP_WITH_TIMEZONE);
|
config.setProperty(MappingSettings.PREFERRED_INSTANT_JDBC_TYPE, SqlTypes.TIMESTAMP_WITH_TIMEZONE);
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -897,10 +900,22 @@ In particular, Hibernate is very careful in how it handles time zones.
|
||||||
|
|
||||||
[WARNING]
|
[WARNING]
|
||||||
====
|
====
|
||||||
Unfortunately, most SQL databases feature embarrassingly poor support for timezones.
|
Unfortunately, with the notable exception of Oracle, most SQL databases feature embarrassingly poor support for timezones.
|
||||||
Even some databases which do supposedly support `TIMESTAMP WITH TIME ZONE` simply covert the datetime to UTC.
|
Even some databases which do supposedly support `TIMESTAMP WITH TIME ZONE` simply covert the datetime to UTC.
|
||||||
Here, Hibernate is limited by the capabilities of the databases themselves, and so on many databases, time zone information will not, by default, be preserved for an `OffsetDateTime` or `ZonedDateTime`.
|
Here, Hibernate is limited by the capabilities of the databases themselves, and so on many databases, time zone information will not, by default, be preserved for an `OffsetDateTime` or `ZonedDateTime`.
|
||||||
The still-experimental annotation link:{doc-javadoc-url}org/hibernate/annotation/TimeZoneStorage.html[`@TimeZoneStorage`] provides some additional options in case the default behavior falls short.
|
====
|
||||||
|
|
||||||
|
[TIP]
|
||||||
|
====
|
||||||
|
The still-experimental annotation link:{doc-javadoc-url}org/hibernate/annotations/TimeZoneStorage.html[`@TimeZoneStorage`] provides some additional options in case the default behavior falls short.
|
||||||
|
//
|
||||||
|
// [source,java]
|
||||||
|
// ----
|
||||||
|
// @TimeZoneStorage(COLUMN)
|
||||||
|
// @TimeZoneColumn(name = "event_offset")
|
||||||
|
// @Column(name = "event_timestamp")
|
||||||
|
// private OffsetDateTime eventDateTime;
|
||||||
|
// ----
|
||||||
====
|
====
|
||||||
|
|
||||||
[[embeddable-objects]]
|
[[embeddable-objects]]
|
||||||
|
|
Loading…
Reference in New Issue