Question: Deserialization of JavaScript array to Java LinkedHashSet using Jackson and Spring doesn't remove duplicates

Question

Deserialization of JavaScript array to Java LinkedHashSet using Jackson and Spring doesn't remove duplicates

Answers 3
Added at 2016-12-31 09:12
Tags
Question

Let's say I have this client-side JSON input:

{
   id: "5",
   types: [
      {id: "1", types:[]},
      {id: "2", types:[]},
      {id: "1", types[]}
   ]
}

I have this class:

class Entity {
    private String id;
    private Set<Entity> types = new LinkedHashSet<>();

    public String getId() {
        return this.id;
    }

    public String setId(String id) {
        this.id = id;
    }

    public Set<Entity> getTypes() {
        return types;
    }

    @JsonDeserialize(as=LinkedHashSet.class)
    public void setTypes(Set<Entity> types) {
        this.types = types;
    }

    @Override
    public boolean equals(Object o){
        if (o == null || !(o instanceof Entity)){
            return false;
        }
        return this.getId().equals(((Entity)o).getId());
    }
}

I have this Java Spring endpoint where I pass the input in the body of a POST request:

@RequestMapping(value = "api/entity", method = RequestMethod.POST)
public Entity createEntity(@RequestBody final Entity in) {
    Set<Entity> types = in.getTypes();
    [...]
}

I would like in:

Set<Entity> types = in.getTypes();

to have only two entries in the correct order... since one of them is a duplicate based on the id... Instead I get duplicates in the LinkedHashSet (!)

I thought from the code I have that removing duplicates would work automatically, but apparently it is not.

This question has a broader context than Why do I need to override the equals and hashCode methods in Java? since it is using implicit Jackson serialization through Java Spring.

Answers to

Deserialization of JavaScript array to Java LinkedHashSet using Jackson and Spring doesn&#39;t remove duplicates

nr: #1 dodano: 2016-12-31 09:12

You'll need to override hashCode() method in Entity class as both hashCode() and equals() method are required to be properly implemented to work with Hash based collections.


More on this:

nr: #2 dodano: 2016-12-31 09:12

Assuming that if the members of Entity class i.e. the id and type are same then the object of class Entity is same is completely wrong unless and until you override the hashcode() and equals() function explicitly.

If you do not override the hashCode() and equals() function in your Entity class then the two objects will be different even though they have same data within their members.

nr: #3 dodano: 2016-12-31 10:12

In Java, objects equality is determined by overriding the equals() and hashcode() contract.

There are default implementations of equals() and hashCode() in Object. If you don't provide your own implementation, those will be used. For equals(), this means an == comparison: the objects will only be equal if they are exactly the same object.

Answer to your question : Objects in LinkedHashSet are inheriting default behaviour of eqauls() and hashcode() methods from Object class. Override eqauls() and hashcode() of Entity class of LinkedHashSet

See below this for default behaviour of hashcode() and equals().

Source Show
◀ Wstecz