2009-04-16 8 views
17

Un problème auquel je suis souvent confronté avec Hibernate est d'avoir une liste (appelez-la listA) d'objets que je veux persister contre une entité (myEntity) mais de les comparer d'abord à la liste existante sur l'entité et supprimer ceux qui ne sont pas dans la listeA. La manière simple de faire ceci est effacer la liste sur l'Entité et ajouter juste tout de la listeA à l'entité, cependant je dois souvent effectuer une certaine validation sur les éléments avant qu'ils soient supprimés - par exemple. pour vérifier si cet utilisateur est autorisé à les supprimer.Hibernate: Meilleure façon de supprimer des éléments dans une collection

Mon approche actuelle se sent maladroit:

//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); 
    } 
} 

Toute place à l'amélioration?

Merci.

Répondre

10

Essayez d'utiliser:

myEntity.getObjectAList().removeAll(listA); 

cela ne fera que garder les objets qui ne sont pas déjà en listeA.

En outre, si vous avez besoin de faire quelque chose comme ceci manuellement à l'avenir, utilisez un itérateur:

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

Alors it.next() vous donnera le prochain élément du tableau, et it.remove() supprimera la dernière valeur de next() pour vous, sans donner d'exception si vous continuez à boucler.

Si vous devez également avoir la possibilité d'ajouter une nouvelle valeur lors de la mise en boucle, pensez plutôt à utiliser listIterator().

+0

Je ne peux pas utiliser removeAll() car j'ai besoin d'effectuer une validation sur les éléments individuellement avant les supprimer. Merci pour le conseil de l'itérateur. – Damo

+2

Je pense que le but de removeAll était de réduire la liste de vos objets à ceux dont vous avez besoin de vérifier la suppression. Ensuite, vous vérifiez tous ceux et supprimez si autorisé. Ensuite, vous pouvez ajouter toute la listeA sans vérifier si elles sont déjà présentes parce que vous les avez déjà supprimées. – digitaljoel

16

Je sais que cette question est assez ancienne, mais j'ai couru dans le même problème et je pense que les réponses données n'étaient pas suffisantes. Ainsi, vous pouvez obtenir exactement le résultat que vous souhaitez en ajoutant la propriété "orphanRemoval=true" à votre annotation de mappage. La suppression des orphelins fonctionne de cette façon (comme décrit dans la page 136 du livre "Beginning Java EE 6 Platform avec GlassFish 3":

"[...] le code supprimera automatiquement l'entité Adresse lorsque le client est supprimé, ou lorsque la relation est rompue (en mettant à null l'attribut d'adresse ou par retirer l'entité enfant de la collection dans un à plusieurs cas) ».

C'est, si vous supprimez un élément d'un collection mappée avec suppression orpheline, puis fusionner l'entité, cet élément sera également supprimé

Questions connexes