Hibernate:删除集合中元素的最佳方法

时间:2009-04-16 14:54:02

标签: java hibernate

我经常面对Hibernate的一个问题是有一个列表(称之为listA)我希望对实体(myEntity)持久化的对象,但必须首先将它们与实体上的现有列表进行比较并删除那些不在listA。

执行此操作的简单方法是清除实体上的列表,然后将所有listA添加到实体中,但是在删除元素之前我经常需要对元素执行一些验证 - 例如。检查是否允许该用户删除它们。

我目前的方法感觉很尴尬:

//Delete the elements that have been removed
//Use toArray to avoid ConcurrentModificationException
for(ObjectA a : myEntity.getObjectAList().toArray(new ObjectA[myEntity.getObjectAList().size()])) {
    if(!listA.contains(a)) {

        //Check if this element can be deleted
        if(canDelete(a)) {
            entityManager.remove(a);
            myEntity.getObjectAList().remove(a);
        }
    }
}

//Add the elements that don't already exist
for(ObjectA a : listA) {
    if(!myEntity.getObjectAList().contains(a)) {
        myEntity.getObjectAList().add(a);
    }
}

还有改进空间吗?

感谢。

2 个答案:

答案 0 :(得分:18)

我知道这个问题已经很老了,但我遇到了同样的问题,我认为给出的答案还不够。因此,您可以在确切的结果中实现,只需将属性"orphanRemoval=true"添加到映射注释即可。孤立删除以这种方式工作(如“使用GlassFish 3开始Java EE 6平台”一书的第136页所述:

“[...]代码将在删除客户时或关系中断时自动删除地址实体(通过将地址属性设置为null或通过从集合中删除子实体< / strong>在一对多的情况下)“。

也就是说,如果从使用孤立删除映射的集合中删除某个项目然后合并该实体,则该项目也将被删除。

答案 1 :(得分:11)

尝试使用:

myEntity.getObjectAList().removeAll(listA);

这只会保留未在listA中的对象。

此外,如果您将来需要手动执行此类操作,请使用迭代器:

Iterator<?> it = myEntitiy.getObjectAList().iterator();
while (it.hasNext())
{
    ...
}

然后it.next()将为你提供数组中的下一个项目,it.remove()将为你删除next()的最后一个值,如果你继续循环则不会给出异常。

如果您还需要在循环时添加新值,请考虑使用listIterator()代替。