Hello, I'm using hibernate 2.1.4 with MSSQL 2000. I'm encountering a problem with unchanged objects being flushed back to the database. The hibernate log is showing an unchanged timestamp column as being dirty.
I patched class TimestampType and added some logging to equals(). What I am seeing is the timestamps appear to be the same, but looking carefully, x.getTime() is returning milliseconds, while y.getTime() is not. For instance:
(TimestampType.java:70) - TimestampType.equals(x=2004-06-06 17:23:08.92, y=2004-06-06 17:23:08.92) equals=false
(TimestampType.java:77) - TimestampType.equals(xTime=1086560588920 yTime=1086560588000)
(TimestampType.java:78) - TimestampType.equals(xts=true yts=true)
(TimestampType.java:85) - TimestampType.equals(xNanos=920000000 yNanos=920000000)
(TimestampType.java:87) - TimestampType.equals(xTime=1086560589840 yTime=1086560588920)
(AbstractEntityPersister.java:274) - com.foo.ClientTransactionClass.createStamp is dirty
(SessionImpl.java:2529) - Updating entity: [com.foo.ClientTransactionClass#CTT000000369001]
What I don't understand is that at line 70, the values for both x.toString() and y.toString() both display 92 milliseconds. However, yTime [y.getTime()] is missing the milliseconds. Line 70 also shows that x.equals(y) returns false. Line 85 shows 92 milliseconds for both x and y.
The updated TimestampType.equals() method is below.
Thanks for your help,
Dave
Code:
public boolean equals(Object x, Object y) {
if (x==y) return true;
if (x==null || y==null) return false;
log.debug("TimestampType.equals(x=" + x + ", y=" + y + ") equals=" + x.equals(y));
long xTime = ( (java.util.Date) x ).getTime();
long yTime = ( (java.util.Date) y ).getTime();
boolean xts = x instanceof Timestamp;
boolean yts = y instanceof Timestamp;
log.debug("TimestampType.equals(xTime=" + xTime + " yTime=" + yTime + ")");
log.debug("TimestampType.equals(xts=" + xts + " yts=" + yts + ")");
int xNanos = xts ? ( (Timestamp) x ).getNanos() : 0;
int yNanos = yts ? ( (Timestamp) y ).getNanos() : 0;
xTime += xNanos / 1000000;
yTime += yNanos / 1000000;
log.debug("TimestampType.equals(xNanos=" + xNanos + " yNanos=" + yNanos + ")");
log.debug("TimestampType.equals(xTime=" + xTime + " yTime=" + yTime + ")");
if ( xTime!=yTime ) return false;
if (xts && yts) {
// both are Timestamps
int xn = xNanos % 1000000;
int yn = yNanos % 1000000;
log.debug("TimestampType.equals(" + xn + ", " + yn + ")->" + (xn==yn));
return xn==yn;
}
else {
// at least one is a plain old Date
return true;
}
}