Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

removeif() not working on list returned by jpa

Tags:

java

jpa

jpql

I've some problem understanding why I can't use removeIf() on a collection returned by jpa but I can use an iterator to do so.

@PersistenceContext(unitName = "my-pu")
private EntityManager em;
@Override
public void removeUserFromGroup(String username, Group group) {
    Query query = em.createNamedQuery("Group.getByName", Group.class);
    query.setParameter("name", group.getGroupName());
    Group qGroup = (Group) query.getSingleResult();
    // this works
    // Iterator<User> i = qGroup.getUsers().iterator();
    // while (i.hasNext()) {
    // User o = i.next();
    // if (o.getUsername().equals(username)) {
    // System.out.println("eqqq");
    // i.remove();
    // }
    // }
    System.out.println("class: " + qGroup.getUsers().getClass().getName());
    // org.eclipse.persistence.indirection.IndirectList
    qGroup.getUsers().removeIf(u -> u.getUsername().equals(username));// doesn't work
}
like image 516
Ced Avatar asked Sep 05 '15 07:09

Ced


Video Answer


1 Answers

The typical reason for such strange behaviour is that you have custom implementations of hashCode (and equals). If in such case you change the object and that causes the hashCode to be different, then with JDK collections it is impossible to remove the object from a Set even with iterator.remove(). The JDK collections do implement the remove by recalculating the hashCode and performing a deletion of the object with that hash. If the hash has changed the removal fails and that is ignored by JDK implementations though they return true as result of the removal what implies that the collection has actually changed even tough it did not. Sad but true.

like image 64
Jörg Avatar answered Sep 28 '22 00:09

Jörg