max wrote:
Your equals method has to be in sync with what the hashcode returns - how do you prevent it from being equal to something that has the same primarykey, but which hashcode were calculated before it got a primarykey ?
x.hashcode();
session.save(x);
flush/commit/etc.
otherx = session2.load(x.class, x.id)
otherx.equals(x) but x.hashcode()!=otherx.hashcode() meaning if x is in a set somewhere set.contains(otherx) will be false even though it is not.
This is indeed a very valid point, and a very real problem.
It is to some degree a point covered in the comments I wrote in the other thread:
Code:
/**
* .....
* If an object is in a HashSet (or similar) prior to being newly persisted, it will at least be recoverable
* by using the exact same object reference, but will not be recoverable by a new reference created using session.load(Class, Serializable).
* .....
*/
In my app this is addressed with my "re-binding" semantics. session.flush() only occurs at the end of the HttpRequest, and therefore x will always be detached at this point.
If x is stored in the HttpSession (or a Collection/Map thereof) then it found and refreshed when the next HttpRequest starts, using session.merge() if the session is to be R/W or with session.get() if the session is to be R/O.
If x is not picked up in this way, then it remains "stale" - it does indeed brake the hashCode(), but much much worse than this, it is a duplicate object which has the potential to throw a NonUniqueObjectException if it becomes involved with any part of a persistent parent/child tree. In other words, the object is useless, and I throw it out into the garbage.
Ok, I looked it over and I concede. Without that "re-bind" activity, this kind of hashCode() could be dangerous.