Support instant-like temporal types

XMLWordPrintableJSON

    • 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.

            Assignee:
            Unassigned
            Reporter:
            Jeffrey Yemin
            None
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: