Jackson bug (or feature!?) when using java.util.Se

2019-05-24 14:41发布

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

2条回答
霸刀☆藐视天下
2楼-- · 2019-05-24 15:13

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

查看更多
唯我独甜
3楼-- · 2019-05-24 15:25

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;
}   
查看更多
登录 后发表回答