openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jody Grassel (Commented) (JIRA)" <>
Subject [jira] [Commented] (OPENJPA-624) QueryKey hashCode is inconsistent with equals
Date Tue, 06 Mar 2012 20:17:58 GMT


Jody Grassel commented on OPENJPA-624:

It seems pretty unlikely that this would make CacheMap unusable in some environment.  If anything,
changing the hashcode algorithm in the middle of a stream is more then likely going to break
anyone relying on a distributed cache (at minimum, it would require every member system to
update) or a cache that stores content to secondary storage that survives JVM lifespans.

I looked at the methods involved:                                       
    public boolean equals(Object ob) {                                  
        if (this == ob)                                                 
            return true;                                                
        if (ob == null || getClass() != ob.getClass())                  
            return false;                                               
        QueryKey other = (QueryKey) ob;                                 
        return StringUtils.equals(_candidateClassName,                  
            && _subclasses == other._subclasses                         
            && _ignoreChanges == other._ignoreChanges                   
            && _rangeStart == other._rangeStart                         
            && _rangeEnd == other._rangeEnd                             
            && ObjectUtils.equals(_query, other._query)                 
            && ObjectUtils.equals(_params, other._params);              
   public int hashCode() {                                              
        int code = 37 * 17 + _candidateClassName.hashCode();            
        if (_query != null)                                             
            code = 37 * code + _query.hashCode();                       
        if (_params != null)                                            
            code = 37 * code + _params.hashCode();                      
        return code;                                                    
OpenJPA-624 raises an issue over the fact that hashCode() does not      
factor in _subclasses, _ignoreChanges, _rangeStart, and _rangeEnd into  
the hashcode value generation, where those fields are all considered    
in equality checking.                                                   
The authority on the subject, the Java API documentation, states:       
public int hashCode()                                                   
    Returns a hash code value for the object. This method is supported  
for the benefit of hashtables such as those provided by                 
    The general contract of hashCode is:                                
        Whenever it is invoked on the same object more than once during 
an execution of a Java application, the hashCode method must            
consistently return the same integer, provided no information used in   
equals comparisons on the object is modified. This integer need not     
remain consistent from one execution of an application to another       
execution of the same application.                                      
        If two objects are equal according to the equals(Object) method,
then calling the hashCode method on each of the two objects must produce
the same integer result.                                                
        It is not required that if two objects are unequal according to 
the equals(java.lang.Object) method, then calling the hashCode method on
each of the two objects must produce distinct integer results. However, 
the programmer should be aware that producing distinct integer results  
for unequal objects may improve the performance of hashtables.          
The key points is that if a == b, then a.hashCode must == b.hashCode.   
However, if a != b, it is still okay that a.hashCode == b.hashCode -- in
that situation equals() is required to validate if two objects are the  
same or not; a hashcode is simply a much faster arithmatic way of       
approaching it (but is not 100% foolproof because there is always the   
risk of a hashcode collision).                                          

> QueryKey hashCode is inconsistent with equals
> ---------------------------------------------
>                 Key: OPENJPA-624
>                 URL:
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: datacache
>    Affects Versions: 1.1.0
>            Reporter: Matthias Seidel
> The hashCode method of QueryKey is implemented to make use of _candidateClassName, _query
and _params while the equals method also considers _rangeStart, _rangeEnd and some other stuff.
This makes them inconsistent and while this seems to work in a CacheMap it makes it unusable
in some other environment e.g. a custom QueryCache implementation.

This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:!default.jspa
For more information on JIRA, see:


View raw message