I am using hibernate and have bi-directional relations. How should I correctly override equals() for both classes.
Here is the code (using guava-Objects): (PS: This is a bad example and choice of entities, but I am interested in learning the recommended way to go about it)
Destination:
@Entity
@Table(name = "DESTINATION")
public class Destination{
private Integer id;
private String name;
private Set<DestinationAlias> aliases = new HashSet<DestinationAlias>(0);
@Override
public boolean equals(Object obj) {
if(obj == this) return true;
if(obj instanceof Destination){
final Destination otherDestination = (Destination) obj;
return Objects.equal(getName().toUpperCase(), otherDestination.getName().toUpperCase())
&& Objects.equal(getAliases(), otherDestination.getAliases());
}
return false;
}
}
DestinationAlias:
@Entity
@Table(name = "DESTINATIONALIAS")
public final class DestinationAlias {
private Integer idDestinationAlias;
private String alias;
private Destination mainCity;
@Override
public boolean equals(Object obj) {
if(obj == this) return true;
if(obj instanceof DestinationAlias){
final DestinationAlias otherAlias = (DestinationAlias) obj;
return Objects.equal(getAlias().toUpperCase(), otherAlias.getAlias().toUpperCase())
&& Objects.equal(getMainCity(), otherAlias.getMainCity());
}
return false;
}
}
This is the test case:
@Test
public void testEqualsto(){
Destination dest = new Destination("abc", 1.0f, 1.0f);
dest.getAliases().add(new DestinationAlias("abc alias", dest));
Destination dest1 = new Destination("abc", 1.0f, 1.0f);
dest1.getAliases().add(new DestinationAlias("abc alias", dest1));
assertEquals(dest, dest1);
}
As expected, stackoverflow occurs, since each equals() in turns calls the other equals() and a cycle occurs.
What is the recommended way to override equals() for bidirectional entities.
We have to deconflict manually. In
DestinationAliasI’d change theequalsexpression so that it will compare the Destionation IDs only (they should be unique):Further Reading