-
Type:
New Feature
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Model
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Scope
Support the Java temporal types that denote a point on the timeline, mapping each to BSON Date as a true instant, alongside the already-supported java.time.Instant:
- java.util.Date
- java.sql.Timestamp
- java.time.OffsetDateTime
- java.time.ZonedDateTime
Time zone storage
The dialect reports TimeZoneSupport.NONE, so an unconfigured application resolves to NORMALIZE_UTC, and hibernate.timezone.default_storage of AUTO resolves to COLUMN. Strategies resolve per attribute through @TimeZoneStorage, not only globally, so every value is reachable.
- NORMALIZE_UTC: supported. One BSON Date. Instant preserved, reads return UTC.
- COLUMN: supported. A BSON Date plus an Int32 offset-seconds field, named after the property with a _tz suffix by default and renameable with @TimeZoneColumn. The offset is preserved; a named zone still degrades to a fixed offset, because ZonedDateTimeCompositeUserType reconstructs with ZonedDateTime.ofInstant.
- NORMALIZE: supported. One BSON Date. Instant preserved, reads return the JVM default zone.
- NATIVE: rejected at boot. MongoDB has no zone-carrying type. Hibernate already rejects it globally, but per attribute it is unguarded today and fails at write instead.
COLUMN combined with @Version, or with a plural attribute, is rejected at boot. Both break inside Hibernate rather than in our code, and neither has a MongoDB-side remedy. COLUMN with @Version trips an assert in VersionResolution.resolve, which is invisible without assertions enabled; COLUMN with a plural attribute throws ClassCastException in OffsetDateTimeCompositeUserType.getPropertyValue, which receives the whole collection.
TIMESTAMP semantics
Register a JdbcType for SqlTypes.TIMESTAMP that binds the value's epoch milliseconds, so hibernate.jdbc.time_zone becomes a no-op for these types as it already is for Instant. The point is not only round-trip fidelity: every BSON Date the extension writes must mean an instant, because the datetime operators in HIBERNATE-88 require a Date operand and are applied uniformly with a UTC timezone argument. Wall-clock TIMESTAMP semantics would store a shifted instant that other readers of the collection would misinterpret.
Precision
BSON Date holds milliseconds. Narrow by rounding to the nearest millisecond, halves going up. Nothing in hibernate-core calls DateTimeUtils.adjustToPrecision, so the rounding belongs in ValueConversions. This changes existing Instant behavior, which truncates today.
Override Dialect.getDefaultTimestampPrecision to return 3. CurrentTimestampGeneration, which backs @CreationTimestamp, @UpdateTimestamp and @CurrentTimestamp with a VM source, builds its clock from that method. At the inherited default of 6 it generates microsecond values that are narrowed on write, so the in-memory entity differs from a re-read.
Not supported
- java.util.Calendar, permanently. MongoDB cannot store the zone, and CalendarJavaType.areEqual compares local field values rather than the instant, so a round trip silently reports inequality on any host whose default zone differs from the writing Calendar's. That corrupts dirty checking, not merely round-trip assertions. TimeZoneStorageHelper offers no COLUMN escape hatch for Calendar.
- @Temporal(DATE) and @Temporal(TIME) on java.util.Date, which force date-only and time-only SQL types.
Boot-time gaps to close
Found while auditing current behavior, and unrelated to each other except that both were uncovered:
- java.time.LocalDate is in neither the supported nor the rejected set. It boots and then fails at write with "setDate not implemented".
- java.time.Period, java.time.YearMonth and java.time.MonthDay silently persist as Java-serialized objects inside a BSON Binary of subtype 0. This is the hazard HIBERNATE-73 was filed for; that ticket is closed having covered only org.bson.types and java.util.UUID.
All four are rejected at boot, so that the representation does not become a compatibility commitment.
Dependency
Depends on HIBERNATE-224. Until that lands, the types added here cannot be supported inside @Struct embeddables or as HQL literals. Shipping them with that gap would be worse than sequencing the two, because Instant already works in both positions.
- depends on
-
HIBERNATE-224 Unwrap domain values in @Struct fields and HQL literals
-
- In Progress
-
- is related to
-
HIBERNATE-226 Support date-only and time-only temporal types
-
- Needs Triage
-