我经常面对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);
}
}
Run Code Online (Sandbox Code Playgroud)
还有改进的余地吗?
谢谢.
Sau*_*rdo 20
我知道这个问题已经很老了,但我遇到了同样的问题,我认为给出的答案还不够.因此,您可以实现精确的结果,只需将属性添加"orphanRemoval=true"到映射注释即可.孤立删除以这种方式工作(如"使用GlassFish 3开始Java EE 6平台"一书的第136页所述:
"[...]代码将在删除客户时或关系中断时自动删除地址实体(通过将地址属性设置为null或通过在一对多中删除集合中的子实体案件)".
也就是说,如果从使用孤立删除映射的集合中删除项目然后合并实体,则此项目也将被删除.
Zac*_*ese 11
尝试使用:
myEntity.getObjectAList().removeAll(listA);
Run Code Online (Sandbox Code Playgroud)
这只会保留listA中尚未存在的对象.
此外,如果您将来需要手动执行此类操作,请使用迭代器:
Iterator<?> it = myEntitiy.getObjectAList().iterator();
while (it.hasNext())
{
...
}
Run Code Online (Sandbox Code Playgroud)
然后it.next()将为您提供数组中的下一项,it.remove()将为您删除next()的最后一个值,如果您继续循环则不会给出异常.
如果您还需要在循环时添加新值,请考虑使用listIterator().