Map Lookups
April 21st, 2009
Throughout the semester I have been enforcing the importance of overriding the equals/hashCode methods where applicable (i.e. domain objects). I just fixed a bug in Spacewalk that was caused by not implementing them, so I figured the real world example might help to illustrate my point.
For the record (not that I imagine people will find this all that interesting), the Bugzilla bug can be found here and the Spacewalk commit here. I’m sure everyone is just racing to read those over now.
I’ll try to keep the setup short. We have a map of capabilities and the key is an architecture type (ArchType). The ArchType class, however, didn’t implement equals/hashCode. So when the map was queried by the architecture type, it used the object reference as the key comparison.
There are some more details I’m not going to fully explain. In short, they are all pulled from the database but the instances themselves are potentially cached. So on the first request to the map, the queried type and the the type inside of the map happened to be the same object, so it pulled the result successfully. On subsequent tries however, the caching ended up causing the two instances to be different (despite containing the same data). In those cases, the results came back as null and we saw a really weird, almost non-deterministic error.
The fix was simple, override equals/hashCode in ArchType to use the data (in this case, the id) rather than allow the default comparison by object reference. So no matter how many times we recreate the ArchType objects from the database, it won’t be a problem since the key lookup will use the data inside of the objects, not their references.
Overriding equals and hashCode. Learn it. Live it. Love it.

