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
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With