Equals implementation

If you try out this mapping, you will be surprised about the amount of queries generated if you update or delete an element of the collection.

If your pizza has 3 ingredients and you will delete one, you will find the following queries.

delete from Pizza_ingredients where Pizza_id=? and name=?
delete from Pizza_ingredients where Pizza_id=? and name=?
delete from Pizza_ingredients where Pizza_id=? and name=?
insert into Pizza_ingredients (Pizza_id, name) values (?, ?)
insert into Pizza_ingredients (Pizza_id, name) values (?, ?)

Hibernate is deleting all ingredients and re-inserts the 2 which persist. The reason is simple. If you do not implement equals and hashcode, Hibernate has no way to detect which element you have removed.

Once you have added an equals method like the following, removing an ingredient will only cause a single delete.

Extract of Ingredient class. 

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Ingredient)) return false;

    Ingredient that = (Ingredient) o;
    if (!name.equals(that.getName())) return false;
    return true;
}

@Override
public int hashCode() {
    return name.hashCode();
}

You need to take greatest care, when implementing equals and hashCode. Hibernate has additional requirements. Please have a look in the chapter Equals and HashCode the section called “Equals and Hashcode”.