Here's my take on the Oracle Date problem. Please let me know if I'm
off-base or if I've overlooked an option.
Oracle has two fields for representing a date.
DATE is what's been around since Oracle 8 and is accurate to the
millisecond.
TIMESTAMP was introduced in Oracle 9 and is much more precise.
Java JDBC specifies three sql data types:
java.sql.Time (only holds hour, minute, second, millisecond values)
java.sql.Date (only holds year, day, month values)
java.sql.Timestamp (Holds year, day, month, hour, minute, second,
millisecond, nanosecond values)
Java itself represents time as java.util.Date objects (Holds year, day,
month, hour, minute, second, millisecond values).
All java.util.Date objects have to be converted to an SQL type to be sent to
the database driver.
The problem appears to be that with the Oracle 9 driver, storing a
java.sql.Timestamp into a DATE field rounds to the nearest millisecond.
However, comparing a java.sql.Timestamp to a DATE field does not round the
Timestamp. Thus, there is no way using the Oracle driver to compare a
Timestamp with a DATE, such as WHERE paymentDate = ? [bound to a Timestamp]
in an optimistic locking statement.
This was not the case with the Oracle 8 driver since there was no notion of
precision greater than milliseconds.
(This would also explain why making WebObjects zero all timestamp fractional
second fields solved the problem last year when we switched from Oracle 8 to
9.)
So what are my options?
I can change all DATE fields to TIMESTAMP fields in the database. This
seems to work, but requires a lot of changes to our production and
development databases.
I can ask Oracle to fix the driver to allow DATE values to be compared the
same way they are stored. While this makes complete sense, I don't think
it'll happen based on my experiences last year.
I can round all dates to the nearest millisecond in code before sending them
to Oracle. I guess this would need to be done as a modification to the
Oracle adapter classes.
Another possibility might be to change all code to represent dates as
java.sql.Timestamps rather than as java.util.Dates in my model. I think
Cayenne currently supports a non-java.util.Date class in the model by
default.
Any suggestions?
-Mike
This archive was generated by hypermail 2.0.0 : Mon Feb 16 2004 - 14:35:32 EST