循环 equals() 导致堆栈溢出
我正在使用休眠并且有双向关系。我应该如何正确地重写这两个类的 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我们必须手动消除冲突。在
DestinationAlias
中,我将更改equals
表达式,以便它仅比较目标 ID(它们应该是唯一的):进一步阅读
We have to deconflict manually. In
DestinationAlias
I'd change theequals
expression so that it will compare the Destionation IDs only (they should be unique):Further Reading