循环 e​​quals() 导致堆栈溢出

发布于 2025-01-05 04:36:06 字数 1950 浏览 4 评论 0原文

我正在使用休眠并且有双向关系。我应该如何正确地重写这两个类的 equals() 。

这是代码(使用番石榴对象):(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() 的推荐方法是什么。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

携君以终年 2025-01-12 04:36:06

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

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

进一步阅读

We have to deconflict manually. In DestinationAlias I'd change the equals expression so that it will compare the Destionation IDs only (they should be unique):

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

Further Reading

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文