hgilde wrote:
Rob, I completely disagree with the implementation that you're talking about, which Mel posted on 2/25. Think through Mel's code and you'll see other logical inconsistencies. For every inconsistency that you fix, you'll open another one.
The problem is that *all* these options have logical inconsistencies. It is all a space of tradeoffs. Java object identity, relational equality, and Hibernate-assigned persistent identity all have different semantics. Which semantics you want for your objects is a design choice that you make up front, and any possible choice will mean that some "natural" code will break.
Quote:
Now, depending on your implementation, you must choose one of these with respect to how equals and hadhCode figure out equality, you can't implement more than one of these without getting into trouble:
You can get into trouble in each of the individual scenarios you describe.
Quote:
An object's identity depends on it's Hibernate key, in which case you should not be comparing objects before saving them. Note that adding an object to a Set will compare it to other members of the set and so, shouldn't be done.
In other words, you get into trouble if you do it. This is the kind of model that breaks my multi-Cat example above.
Quote:
Its identity depends on the other, non-ID fields, in which case you can compare non-persisted objects but you can't expect Hibernate to know if a new object should be saved or updated without an explicit hint. They recommend this approach.
Actually, can't you have a private property for the Hibernate ID and let Hibernate use that to figure it out? (i.e. it's an implicit, Hibernate-managed hint?) The trouble here is that you may not *have* any such non-ID fields, as in my Cat example -- cat1 and cat2 are different cats whether they have the same name or not.
Quote:
Its identity depends on both the Hibernate key and the other, non-id fields, in which case you should expect (in the code) the identity to change when you first save the object.
The trouble here (obviously) is that you will be breaking collections with no way to fix them.
Quote:
Its identity is based on it's JVM object ID (memory location). This, IMHO, is a bad idea for domain objects. See chapter 3 of Effective Java: "A programmer who compares references to value objects using the equals method expect to find out whether they are logically equivalent, not whether they refer to the same object.".
The quote you cite refers to *value* objects. *Domain* objects have individual identity potentially regardless of any of their field properties. (OK, this is arguable, but certainly not in principle inconceivable.)
Overall, actually, I agree with you that it is likely better to make just one choice for your semantics of object identity. But you can't justify that choice simply on the basis of avoiding trouble -- there are different kinds of trouble with any choice you can make. Mel's technique has its own kinds of trouble, but that (to me) doesn't disqualify it as just one more possibility.
Cheers,
Rob