Java Hibernate:删除集合中元素的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/756513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate : Best way to delete elements in a collection
提问by Damo
A problem that I often face with Hibernate is having a list (call it listA) of objects that I want to persist against an entity (myEntity) but having to first compare them to the existing list on the entity and delete those that aren't in listA.
我在 Hibernate 中经常遇到的一个问题是有一个对象列表(称为 listA),我想针对实体 (myEntity) 保留这些对象,但必须首先将它们与实体上的现有列表进行比较,然后删除那些不是在列表A中。
The simple way to do this is to clear the list on the Entity and just add all of listA to the entity, however I often have to perform some validation on the elements before they are deleted - eg. to check whether this user is allowed to delete them.
执行此操作的简单方法是清除实体上的列表,然后将所有 listA 添加到实体中,但是我经常需要在元素被删除之前对其进行一些验证 - 例如。检查是否允许该用户删除它们。
My current approach feels awkward:
我目前的方法感觉很尴尬:
//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);
}
}
Any room for improvement?
还有改进的余地吗?
Thanks.
谢谢。
采纳答案by Zack Marrapese
Try using:
尝试使用:
myEntity.getObjectAList().removeAll(listA);
this will only keep the objects which aren't already in listA.
这只会保留不在 listA 中的对象。
Also, if you need to do something like this manually in the future, use an iterator:
此外,如果您将来需要手动执行此类操作,请使用迭代器:
Iterator<?> it = myEntitiy.getObjectAList().iterator();
while (it.hasNext())
{
...
}
Then it.next() will give you the next item in the array, and it.remove() will remove the last value of next() for you, without giving an exception if you keep looping.
然后 it.next() 将为您提供数组中的下一项,it.remove() 将为您删除 next() 的最后一个值,如果您继续循环,则不会出现异常。
If you need to also have the ability to add a new value while looping, consider using listIterator() instead.
如果您还需要能够在循环时添加新值,请考虑改用 listIterator()。
回答by Saul Berardo
I know this question is quite old, but I ran in the same problem and I think the answers given were not enough. So, you could achieve at the exact result you want just adding the property "orphanRemoval=true"
to you mapping annotation. Orphan removal works this way (as described in the page 136 of the book "Beginning Java EE 6 Platform with GlassFish 3":
我知道这个问题已经很老了,但我遇到了同样的问题,我认为给出的答案还不够。因此,您只需将属性添加"orphanRemoval=true"
到映射注释即可获得您想要的确切结果。孤儿移除以这种方式工作(如“使用 GlassFish 3 开始 Java EE 6 平台”一书的第 136 页中所述:
"[...] the code will automatically remove the Address entity when the customer is removed, or when the relationship is broken (by setting to null the address attribute or by removing the child entity from the collectionin a one-to-many case)".
“[...] 当客户被移除或关系中断时,代码将自动移除 Address 实体(通过将 address 属性设置为 null 或通过一对多的方式从集合中移除子实体)案件)”。
That is, if you remove an item from a collection mapped with orphan removal and then merge the entity, this item will be also removed.
也就是说,如果您从使用孤儿删除映射的集合中删除一个项目,然后合并该实体,则该项目也将被删除。