Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set remove() function does not work

while working with my application I've encountered a problem while trying to remove object from the java collection ( Set pulled from database with EclipseLink ). The object which I want to remove in an entity class which has overriden equals method. I've even checked whether any of the objects in the collection is eqauls to the one I want to remove with the following code:

for(AlbumEntity entity : deleteGroup.getAlbums()){
    System.out.println("VAL: " + deleteAlbum.equals(entity));
}

In this case, one of the values returned is true. However, if I do:

boolean result = deleteGroup.getAlbums().remove(deleteAlbum);

the value of result is false and the size of collection stays the same.

Thanks for your help in advance

edit:

@Override
public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
}

@Override
    public boolean equals(Object object) {
        if (!(object instanceof AlbumEntity)) {
            return false;
        }
        AlbumEntity other = (AlbumEntity) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }
like image 803
chabrowa Avatar asked Nov 21 '13 23:11

chabrowa


People also ask

How do you use set in remove?

The remove() method removes the specified element from the set. This method is different from the discard() method, because the remove() method will raise an error if the specified item does not exist, and the discard() method will not.

Which function of set raises exception when element not exists in set?

Method 1: Use of discard() method If the element is not present in the set, then no error or exception is raised and the original set is printed.


1 Answers

A few possibilities:

1) There is a problem with the implementation of id's equals or hashCode methods. In this case, you could have id1.equals(id2) but id1.hashCode() != id2.hashCode(). This would cause inconsistency between equals and hashCode() for the album objects and could cause the symptoms you're seeing.

2) The id for one or more albums changes at some point after the for loop that checks deleteAlbum.equals(entity) for each album in the Set. If an id changes for an album, the remove() method may not be able to find it. An id could change from null to some non null number if got saved to the database - EclipseLink might do this for you without you explicitly asking it to.

3) Because of EclipseLink's meddling, deleteGroup might not actually be a HashSet when you run your code. The docs for EclipseLink suggest it will give you an "indirection object" instead of the java.util.Set (or java.util.HashSet I presume) declared in your class, depending on how it is configured. In that case, the contains and remove methods might not do what you expect them to.

See Overriding equals and hashCode in Java for more details on these and other possible problems involving equals and hashCode, which can cause bizarre behavior with Sets.

like image 190
dshiga Avatar answered Oct 25 '22 13:10

dshiga