|
From: Colin S. <col...@ex...> - 2003-07-29 16:09:41
|
jürgen höller [werk3AT] wrote: >Everyone, > >A rather general problem that I've been wondering about for a while: "equals"/"hashCode" implementation for entities with an externally determined ID. > >I've repeatedly discovered issues with primary-key-based implementations of the both. The root cause is adding an entity to a HashSet *before* setting its ID, e.g. when using a MySQL autoincrement column as primary key with Hibernate. Example: Filling a parent folder including some children and then saving them all in one go. A "contains" or "remove" call on the children collection will fail then, as the hash code has changed while the object was in the collection. > >Of course, HashSet states that this is illegal, but how to avoid this? It's especially tricky with m:n associations, e.g. between parents and children. No matter how you load such an object tree, some entities will always get added to a collection in a not fully initialized state, potentially incurring hash code failure when the ID hasn't been set yet. This not only arises with persistence tools like Hibernate but also with remoting tools like Hessian. > >I see various solutions for the problem: > >- Reinitializing the HashSet after the change: This solves the create-then-save issue, but seems like a hack and doesn't address the mutual m:n issue. > > Can you clarify what you mean when you say it doesn't address the mutual m:n issue? Main issue that I see here is really hibernate. If Hibernate and the collections it manages are happy, then I don't care about some transient collection elsewhere that has the original instance of the object with the empty id field (since I don't consider that the same object any longer anyways). But I think with some (a lot of) code Hibernate could track persistent collections (it already does insert a bytecode modified version of each collection anyways, so has some collection handling), track whether an object can potentially be a member of a collection (which it can do based on the mapping data it has), and then on assigning an ID go through all the candidate collections and try to pull out the old instance if it exists and reinsert it properly. I will say, after this conversation, GUIDs are starting to look pretty good :-) Too bad about legacy tables though... |