循环equals()导致stackoverflow

时间:2012-02-13 12:42:54

标签: java hibernate java-ee equals

我正在使用hibernate并且具有双向关系。我应该如何正确地覆盖两个类的equals()。

这是代码(使用guava-Objects):( PS:这是一个不好的例子和实体的选择,但我有兴趣学习推荐的方法去实现它)

目标

@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;
    }
}

这是测试用例:

@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);
}

正如预期的那样,堆栈溢出发生,因为每个equals()轮流调用另一个equals()并发生一个循环。

为双向实体重写equals()的推荐方法是什么。

1 个答案:

答案 0 :(得分:3)

我们必须手动解除冲突。在DestinationAlias中,我会更改equals表达式,以便仅比较Destionation ID(它们应该是唯一的):

return Objects.equal(getAlias().toUpperCase(), otherAlias.getAlias().toUpperCase())
            && Objects.equal(getMainCity().getId(), otherAlias.getMainCity().getId());
                                          ^^^^^^^^                          ^^^^^^^^

进一步阅读