2009-04-16 9 views
17

Un problema che spesso mi trovo ad affrontare con Hibernate è avere una lista (chiamala listaA) di oggetti che voglio perseguire contro un'entità (myEntity) ma dovendoli prima confrontare l'elenco esistente sull'entità ed elimina quelli che non sono in elencoA.Ibernazione: il modo migliore per eliminare elementi in una raccolta

Il modo semplice per eseguire questa operazione è cancellare l'elenco sull'entità e aggiungere semplicemente tutta l'elencoA all'entità, tuttavia spesso devo eseguire alcune convalida sugli elementi prima che vengano eliminati, ad es. per verificare se questo utente è autorizzato a eliminarli.

mio approccio attuale si sente a disagio:

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

Qualsiasi margini di miglioramento?

Grazie.

risposta

10

Provare a utilizzare:

myEntity.getObjectAList().removeAll(listA); 

questo non mancherà di tenere solo gli oggetti che non sono già in Lista.

Inoltre, se avete bisogno di fare qualcosa di simile manualmente in futuro, utilizzare un iteratore:

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

Poi it.next() vi darà la voce successiva nella matrice, e it.remove() rimuoverà l'ultimo valore di next() per te, senza dare un'eccezione se continui a fare il ciclo.

Se è necessario avere anche la possibilità di aggiungere un nuovo valore durante il ciclo, prendere in considerazione l'utilizzo di listIterator().

+0

Non riesco a utilizzare removeAll() poiché è necessario eseguire una convalida rispetto agli elementi singolarmente prima cancellandoli. Grazie per il suggerimento Iterator però. – Damo

+2

Penso che il punto di removeAll fosse che avrebbe ridotto l'elenco sull'oggetto a quelli che è necessario controllare per l'eliminazione. Poi controlli tutti quelli e rimuovi se permesso. Quindi puoi aggiungere tutto il listA senza controllare per vedere se sono già lì perché li hai già rimossi. – digitaljoel

16

So che questa domanda è piuttosto vecchia, ma ho avuto lo stesso problema e penso che le risposte fornite non fossero sufficienti. Pertanto, è possibile ottenere il risultato esatto che si desidera semplicemente aggiungendo la proprietà "orphanRemoval=true" all'annotazione di mapping. La rimozione di Orphan funziona in questo modo (come descritto nella pagina 136 del libro "Beginning Java EE 6 Platform with GlassFish 3":

"[...] il codice rimuoverà automaticamente l'entità Address quando il cliente viene rimosso, o quando la relazione è interrotta (impostando su null l'attributo address o tramite rimuovendo l'entità child dalla raccolta in un caso uno-a-molti). "

Cioè, se si rimuove un elemento da un collezione mappata con rimozione orfana e quindi unire l'entità, verrà rimosso anche questo elemento.

Problemi correlati