使用java.util.Set时的Jackson错误(或功能!?)-mySet.size()始终为1


问题内容

我正在使用Hibernate 4.2.2和Jackson 2.2.0和Spring 3.2.0。

我最近不得不通过POST将一系列对象发送到服务器:

{"cancelationDate":"2013-06-05",
 "positions":[
   {"price":"EUR 12.00",
    "count":1},
   {"price":"EUR 99.00",
    "count":1}
 ]
}

我的课程如下所示:

public class Bill extends {
  LocalDate cancelationDate;

  Set<Position> positions;

  ...
}

和:

public class Position { 
  Integer count;

  BigMoney price;

  @JsonIgnore
  Bill bill;

  ...
}

当我打电话bill.getPositions().size()告诉我1


如果我使用List<Position>代替Set<Position>它,效果很好。那是什么问题Set呢?

谢谢 :)

等于和hashCode:

public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = (int) (prime * result + ((id == null) ? 0 : id.hashCode()));
    return result;
}

public boolean equals(Object obj) {
    if (obj == this)
        return true;
    if (!(obj instanceof Position))
        return false;
    Position equalCheck = (Position) obj;
    if ((id == null && equalCheck.id != null) || (id != null && equalCheck.id == null))
        return false;
    if (id != null && !id.equals(equalCheck.id))
        return false;
    return true;
}

问题答案:

由于杰克逊反序列化位置的id为null,因此hashCode为不同的对象返回相同的值,而equals返回true。集合不能包含等于的元素。解决您的equals
/ hashcode问题,一切都会正常进行。

建议的新hashCode /等于:

public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = (int) (prime * result + ((id == null) ? 0 : id.hashCode()));
    result = (int) (prime * result + ((price== null) ? 0 : price.hashCode()));
    return result;
}

public boolean equals(Object obj) {
    if (obj == this)
        return true;
    if (!(obj instanceof Position))
        return false;
    Position equalCheck = (Position) obj;
    if ((id == null && equalCheck.id != null) || (id != null && equalCheck.id == null))
        return false;
    if (id != null && !id.equals(equalCheck.id))
        return false;
    if ((price== null && equalCheck.price != null) || (price != null && equalCheck.price == null))
        return false;
    if (price!= null && !price.equals(equalCheck.idprice)
        return false;

    return true;
}