removeif()不在jpa返回的列表上工作

时间:2015-09-05 07:17:35

标签: java jpa jpql

我理解为什么我不能在jpa返回的集合上使用removeIf()但我可以使用迭代器来解决这个问题。

id

3 个答案:

答案 0 :(得分:6)

这种奇怪行为的典型原因是你有hashCode(和equals)的自定义实现。如果在这种情况下您更改了对象并导致hashCode不同,那么使用JDK集合即使使用iterator.remove()也无法从Set中删除该对象。 JDK集合通过重新计算hashCode并使用该哈希执行对象的删除来实现删除。如果散列已经更改,则删除失败并且JDK实现会忽略它,尽管它们会因为删除而返回true,这意味着集合实际上已经改变了甚至很难实现。悲伤却又是真的。

答案 1 :(得分:0)

完美,另一条路是抛出一个新列表来解决问题......例如:

if (!CollectionUtils.isEmpty(getEvento().getAtividade())) {
    Set<Atividade> listAtividade = getEvento().getAtividade();
    getEvento().setAtividade(new HashSet<>());
    getEvento().getAtividade().addAll(listAtividade);
}
getEvento().getAtividade().removeIf(a -> 
a.getEspecialidade().getId().equals(especialidade.getId()));
or
getEvento().getAtividade().removeAll(getListAtividadeNotSelected());

答案 2 :(得分:0)

实际答案很可能既不是Equals / Hash(请与@EqualsAndHashCode一起使用Lombok),也不是创建新列表(只是隐藏实际问题)。

实际上,很有可能使用Arrays.asListCollections.singletonList来创建不可变的ArrayList

假设您在JPA中有一个OneToMany / ManyToMany关系,那么一个Collection-让它成为具有成员的Group。组/用户都是正确的JAP @Entity

var user1 = new User();
var user2 = new User();
var group = new Group();


group.addMembers(Arrays.asList(user1,user2));
group = groupRepository.save(group);

// will throw an exception
group.getMembers().removeIf((user) user.getId() == 1);

原因是Arrays.asList(user1,user2)创建了一个具有固定固定大小的实际不可变数组。在其上运行remove会失败,并显示OperationNotSupport

由于Arryas.asListCollections.singletonList总是很笨拙(因为您必须为1+选择前者,而对于1个元素则选择后者),并且在这两种情况下,您都可以使用您可能不知道的不可变数组,可以使用番石榴

Lists.newArrayList(user1,user2);
Lists.newArrayList(user1);

适用于任何大小,并且该数组是可变的。

请注意,如果您使用JPA工具,此问题可能会更加隐蔽,因为它期望列表可变,并且如果操作不当,则可以通过更多的加密异常处理您。