Just wasted some time trying to get a big business logic unit test to pass and tracked it down to this.
Here is a failing test demonstrating just the problem of using System.hashCode for Id values:
@isTest
private class HashCodeTest {
@isTest
static void test() {
Account a = new Account(Name = 'Acme');
insert a;
Id aId = a.Id;
Set<Integer> s1 = new Set<Integer>();
Set<Integer> s2 = new Set<Integer>();
Set<Integer> s3 = new Set<Integer>();
Integer n = 8;
for (Integer i = 0; i < n; i++) {
s1.add(System.hashCode(String.valueOf(a.Id)));
s2.add(System.hashCode(aId));
s3.add(System.hashCode(a.Id));
System.assert(a.Id == a.Id);
}
System.assertEquals(1, s1.size());
System.assertEquals(1, s2.size());
// This fails: same (equals) object but n different hashCodes not 1
System.assertEquals(1, s3.size());
}
}
The last assertion demonstrates the problem: referencing the Id
field of an object returns an Id
object that has a different hashCode
every time (n in the set instead of 1 in the set) even though the Id
values are equal. So the normal equals
/hashCode
contract is violated.
Please comment/answer if I'm missing something here - to me this looks like an Apex bug but I may be deluding myself.
PS
Probably related to but not the same as Id object and String object representing the same entity ID are equal but don't have the same .hashCode().
hashcode
method? You're saying that every time you callSystem.hashCode(a.Id)
you are getting a different integer back?