|
Thanks for your fast answer Juergen. Concerning the hashCode implementation, I admit, it's to give a lot of responsability. It's for me a semantic question, what are the fields representing distinct Object. For me, Codes field is not enough. But could we give this kind of semantic responsability to the hashCode method. May be the equals method should also be modified. However, yes I'm using a specific MessageSource implementation which is, for a specific key, first take a look into a ResouceBundleMessageSource then into a kind of custom DataBaseMessageSource if not found in the first one. My "dispatcher" is imlpementing the MessageSource interface and the results of the following methods are well cached (using SpringModules caching annotation): Thanks I guess the fundamental question here is whether hashCode() is actually supposed to semantically identify its object. The original purpose of hashCode() is simply to choose an appropriate hash bucket in a hash map; such buckets are by their very nature designed to hold multiple objects, in particular ones with the same hash code. Hash codes are not reliably distinct; they're ints, so just imagine a large enough number of objects and hash codes are bound to overlap... Following from that line of reasoning, HashCodeCacheKeyGenerator is inherently fragile. It relies on hashCode() distinctiveness assumptions that are not even demanded by the java.lang.Object documentation. We may refine DefaultMessageSourceResolvable's hashCode() implementation (doesn't hurt to take arguments into account, even if it will lead to more expensive hashCode calculation); nevertheless, it seems that HashCodeCacheKeyGenerator's strategy remains fragile. Juergen Actually, as you pointed out (which I haven't really noticed before), DefaultMessageSourceResolvable's equals(Object) implementation compares the codes field only, assuming that all such resolvables are effectively identifying the same message. This is questionable indeed... since arguments will lead to a different message String getting returned. I'll revisit this. Technically it would be sufficient to revise the equals(Object) implementation here and keep hashCode() as-is. I suppose for the purposes of HashCodeCacheKeyGenerator, we still need to revise the hashCode() implementation as well... Juergen DefaultMessageSourceResolvable and also FieldError implement "equals" and "hashCode" such that all fields are respected now. This should generally be cleaner and also make hashCode-based caching strategies work as far as possible given the fragility of the hashCode contract. This will be available in tonight's 2.5.6 snapshot (http://static.springframework.org/downloads/nightly/snapshot-download.php?project=SPR Juergen Thanks. I keep you informed. Caching is working well now with snapshot spring-framework-2.5.6-20080724-566.zip Thanks Juergen !!! |
||||||||||||||||||||||||||||||||||||||
Well, this is not a bug as far as I see, since a hashCode() implementation is allowed to return a simplified hash key - even a constant value would be valid in principle! hashCode values need to be equal if the equals(Object) returns true... however, they may also be equal if equals(Object) returns false! Distinct integer values should be used in order to improve the performance of hash lookups, but otherwise hashCode values are not required to differ in the first place...
I would rather claim that the HashCodeCacheKeyGenerator strategy is a bit fragile here, given the relaxed hashCode() contract that java.lang.Object defines!
As for your specific use case: Why do you externally cache messages in the first place here? Spring's ResourceBundleMessageSource and ReloadableResourceBundleMessageSource classes perform quite extensive caching already... internal to the MessageSource. Are you using a custom MessageSource implementation there?
Juergen