2014-04-19 12 views
8

Ich habe einige Objekte, die ich nicht löschen kann, und muss stattdessen ein allgemeines Feld namens 'gelöscht' aktualisieren. Ich lese there, dass ich generische Querys schreiben kann, mit #{#entityName}. Aus diesem Grund habe ich versucht, CrudRepository#delete(…) Methode wie folgt außer Kraft zu setzen:Wie überschreibt man eine Löschmethode für ein Spring Data CrudRepository?

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

Aber die habe ich einen Komponententest, die mich falsch zeigt!

@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 

} 

Ist es nicht möglich, CrudRepository Methoden wie das zu überschreiben?

+1

Warum möchten Sie Repository-Löschverhalten ändern und diese Situation in Ihrer Service-Schicht nicht behandeln? – gipinani

+2

, denn wenn ich dies auf Repository-Ebene handhaben könnte, muss ich keine zusätzlichen Dienste oder Daos implementieren. –

Antwort

5

Zum Ändern von Abfragen müssen Sie der Methode @Modifying hinzufügen.

Seien Sie sicher, dass Sie Kenntnis von den Nebenwirkungen der Ansatz, den Sie gewählt haben:

  • ein Manipulieren Abfrage durchführen viel ist ziemlich alle EntityManager Caches umgangen wird. Ein nachfolgender findOne(…) könnte/würde also immer noch die alte Instanz des Objekts, das Sie löschen wollten, zurückgeben, falls die EntityManager diese bereits geladen hatte. Um dies zu verhindern, setzen Sie das Flag clearAutomatically in @Modifying auf true, aber beachten Sie, dass dadurch alle ausstehenden Änderungen gelöscht werden.
  • Für Abfrage basierte Datenmanipulation keine Lifecycle-Callbacks ausgelöst werden und keine Kaskaden werden auf der Ebene des Persistenzkontexts ausgelöst werden. Das bedeutet, dass Entity-Listener, die ein @PreUpdate Event hören, nicht benachrichtigt werden. Auch alle Kaskadenoperationen