Jackson bug (or feature!?) when using java.util.Set - mySet.size() is always 1

假如想象 提交于 2019-12-22 12:43:23

问题


I am using Jackson 2.2.0 and Spring 3.2.0 with Hibernate 4.2.2.

I recently had to send an array of objects via POST to the server:

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

My classes look like this:

public class Bill extends {
  LocalDate cancelationDate;

  Set<Position> positions;

  ...
}

and:

public class Position { 
  Integer count;

  BigMoney price;

  @JsonIgnore
  Bill bill;

  ...
}

When I call bill.getPositions().size() it tells me 1.


If I use List<Position> instead of Set<Position> it works nice. So what's the problem with Set?

Thank you :)

equals and 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;
}   

回答1:


Since id is null for the Jackson deserialized Positions, hashCode returns the same value for the different objects, and equals returns true. A Set cannot contain to elements which are equal. Fix your equals/hashcode implentation and everything will work as it should.

Suggested new hashCode/equals:

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



回答2:


the Set use equals and hashcode methods when it insert a row, have you overriden them?

I had also some bug with jackson 2.2.1 (with Maps) , you should upgrade to jackson 2.2.2



来源:https://stackoverflow.com/questions/16917341/jackson-bug-or-feature-when-using-java-util-set-myset-size-is-always-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!