I think I've read just about every frickin article about equals/hashcode and natural-id. (Fun .... argh). I'm stuck trying to decide how to implement equals for natural-ids that have a many-to-one in it (i.e. the "parent" entity is part of equality).
The problem as I see it is there's no way to include the check for the many-to-one part in the equals method. Doing so would cascade lazy loads as far as the eye can see (if it was still connected to the Session; if no, yikes). So my real question is, is this even possible? I guess the workaround (if you want to call it one) is to just leave out that part of the check and promise never to compare objects from different sets, lists or whatever.
If you take this little example:
Code:
public class Value {
private String foo;
private Parent parent;
public String getFoo() {...}
public void setFoo(String value) {...}
public Parent getParent() {...}
public void setFoo(Parent parent) {...}
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object instanceof Value) {
Value rhs = (Value) object;
return foo.equals(rhs.getFoo());
} else {
return false;
}
}
<hibernate-mapping package="com.sample">
<class name="Foo" table="foo">
<id column="c_id" type="long">
<generator class="identity" />
</id>
<natural-id>
<property name="foo" column="c_foo" type="string" />
<many-to-one name="parent" column="c_parent" />
</natural-id>
</class>
</hibernate-mapping>
And this my wonderful code that breaks this all:
Code:
public void breakme() {
Parent pone = ....
Parent ptwo = ....
Foo fone = new Foo("one", pone);
Foo ftwo = new Foo("one", ptwo);
pone.getFoos().add(fone);
ptwo.getFoos().add(ftwo);
assertFalse(fone.equals(ftwo)); // Fails, of course
}
Okay, that was too much typing for something so obvious? I'm not sure if anybody has had this problem. (Everybody seems to hate natural keys and runs shrieking the other way.)