2014-04-19 6 views
8

Ho alcuni oggetti che non riesco a cancellare e devo aggiornare un campo comune chiamato "cancellato" al posto di esso. Ho letto there che posso scrivere querys generici, usando #{#entityName}. Per questo motivo ho cercato di ignorare CrudRepository#delete(…) metodo come questo:Come sovrascrivere un metodo di cancellazione su un Data CrudRepository Spring?

public interface DeleteableRepository<T, ID extends Serializable> extends CrudRepository<T,ID>{ 

    @Override 
    @Query("UPDATE #{#entityName} x set x.deleted = 1 where x.id = ?1") 
    public void delete(ID id); 
} 

Ma ho una prova di unità che mostra me sbagliato!

@Test 
public void testDelete() { 

    SomeDeleteableObject sdo = new SomeDeletableObject(); 
    sdo = getDeleteableRepository().create(sdo); 

    Assert.assertNotNull(sdo); 
    Assert.assertNotNull(sdo.getId()); 
    Assert.assertFalse(sdo.isDeleted()); 
    getDeleteableRepository().delete(sdo); 

    sdo = getDeleteableRepository().findOne(sdo.getId()); 
    //Fails here 

} 

Non è possibile sovrascrivere i metodi CrudRepository in questo modo?

+1

Perché si desidera modificare il comportamento dell'archivio di eliminazione e non gestire questa situazione nel livello di servizio? – gipinani

+2

perché se potessi gestirlo sul livello del repository non ho bisogno di implementare servizi o Daos extra. –

risposta

5

Per la modifica delle query è necessario aggiungere un metodo @Modifying al metodo.

essere sicuri che siano consapevoli degli effetti collaterali di questo approccio si è scelto:

  • L'esecuzione di una query manipolazione è praticamente bypassando tutti EntityManager cache. Pertanto un successivo findOne(…) potrebbe restituire/restituire la vecchia istanza dell'oggetto che si è tentato di eliminare nel caso in cui lo EntityManager lo avesse già caricato. Per evitare ciò, imposta il flag su @Modifying su true ma tieni presente che ciò causerà la cancellazione di tutte le modifiche in sospeso.
  • Per la manipolazione dei dati basata su query no le richiamate del ciclo di vita verranno attivate e no le cascate verranno attivate al livello del contesto di persistenza. Ciò significa che gli ascoltatori di entità che ascoltano un evento @PreUpdate non riceveranno una notifica. Anche eventuali operazioni in cascata