Skip to content

[OPENJPA-3028] Bind DATE values without their time of day - #280

Merged
solomax merged 2 commits into
masterfrom
OPENJPA-3028-oracle-temporal
Nov 7, 2026
Merged

solomax merged 2 commits into
masterfrom
OPENJPA-3028-oracle-temporal

Conversation

@rzo1

@rzo1 rzo1 commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Values for DATE columns and TemporalType.DATE parameters are bound as date only, in one place. Oracle stored and compared the time of day, so dates never matched. On Oracle, times in DATE columns are bound without fractional seconds.

Rows written by earlier versions keep their time of day; normalise them with TRUNC before upgrading.

rzo1 added 2 commits November 6, 2026 09:48
A java.util.Date or Calendar bound for a DATE column, as the value of a
@TeMPOraL(DATE) attribute or as a parameter, and a parameter set with
TemporalType.DATE were converted with new java.sql.Date(millis), which
keeps the time of day, although a java.sql.Date has to be normalized to
the start of its day. A java.sql.Date holding a time of day was bound
as it was. Most drivers drop the time when binding a date, but the
Oracle driver stores and compares it as part of the DATE value, so a
date attribute or parameter holding a time of day never equalled a
stored date.

Every date bound for a DATE column, or as a parameter without a known
column, whether it is a java.util.Date, a Calendar or a java.sql.Date,
is now bound as the java.sql.Date of its day in the default time zone,
so that the same value binds the same way in an INSERT, in a query
parameter and in a primary key lookup. A java.sql.Date bound with an
explicit Calendar, and a java.sql.Date attribute mapped to a column
that is not of type DATE, are bound as before.

Behaviour change on Oracle: the time of day of a date attribute mapped
to a DATE column (a java.sql.Date, or a java.util.Date or Calendar with
@TeMPOraL(DATE)) is no longer stored, and such values and
TemporalType.DATE parameters are bound as midnight. The time of day of
the value held by the entity in memory is unchanged. Rows written by
earlier versions keep the time of day they were stored with, and no
longer compare equal to the same value bound now: a query on such a
column, em.find on such an id, or an update or delete of a row keyed
by such a column does not find the row. Normalize those columns, for
example with UPDATE <table> SET <column> = TRUNC(<column>), before
upgrading. Databases whose DATE type has no time of day are not
affected.
Times are mapped to DATE columns on Oracle, which drop the fraction of
the second when a value is stored. A LocalTime or OffsetTime parameter
with a fraction of a second was bound with it and so never equalled the
value stored for the same time. A time bound for a DATE column is now
bound without the fraction; columns that can hold it, such as TIMESTAMP
columns, are not affected.
@rzo1
rzo1 requested review from cristof and solomax November 6, 2026 14:16
@solomax
solomax merged commit 5d2c0d3 into master Nov 7, 2026
4 checks passed
@solomax
solomax deleted the OPENJPA-3028-oracle-temporal branch November 7, 2026 03:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants