The following class serve as generic tester for equals/hashCode contract. It is a part of a home grown testing framework.
The notEqualsWorks(Object x, Object y) theory is false: two distinct instances may still be logically equal according to their equals method; you're assuming instances are logically different if they're different references.
Using your own example above, the two distinct datapoints below (a != a2) are nevertheless equal but fail the notEqualsWorks test:
@DataPoint
public static String a = "a";
@DataPoint
public static String a2 = new String("a");