Rule Definition
When checking the equality between two objects or comparing them, before comparing the attribute's value the type equality must be validated. Often the instanceof operator is used to perform this equality, however, the condition fails to return false if the argument is a subclass of the class that is compared. Thus, it might violate the symmetry requirement of the contract (x.equals(y) should return true if and only if y.equals(x) returns true). It is the same for compareTo since the recommended behavior is to use a natural ordering that is consistent with equals.
As a consequence you might have unexpected behavior where two objects are considered equals, greater or less than while they are not and moreover, the result depends on which object the method has invoked.
Remediation
Replace instanceof usage by the comparison of each object class name or using org.hibernate.Hibernate.getClass to get the true, underlying class of a proxied persistent class.
Violation Code Sample
class MyClass {
...
public boolean equals(Object other) {
if (this==other) return true;
if (other==null) return false;
// VIOLATION
if ( !(other instanceof MyClass)) return false;
...
}
...
}
Fixed Code Sample
class MyClass {
...
public boolean equals(Object other) {
if (this==other) return true;
if (other==null) return false;
// FIXED
if (other.getClass() != this.getClass()) return false;
// OR in case of Hibernate
if (!Hibernate.getClass(other).equals(Hibernate.getClass(this)) return false;
...
}
...
}
Reference
http://www.angelikalanger.com/Articles/JavaSolutions/SecretsOfEquals/Equals.html
Related Technologies
JEE
Technical Criterion
Programming Practices - Unexpected Behavior
About CAST Appmarq
CAST Appmarq is by far the biggest repository of data about real IT systems. It's built on thousands of analyzed applications, made of 35 different technologies, by over 300 business organizations across major verticals. It provides IT Leaders with factual key analytics to let them know if their applications are on track.