2014-04-19 44 views
8

我有一些我無法刪除的對象,並且必須更新一個名爲'deleted'而不是它的公共字段。我讀there,我可以使用#{#entityName}編寫通用querys。 出於這個原因,我試圖重寫CrudRepository#delete(…)方法是這樣的:如何覆蓋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); 
} 

但我有一個單元測試,顯示我錯了!

@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 

} 

是不是可以重寫CrudRepository這樣的方法?

+1

爲什麼要修改刪除存儲庫行爲並且不處理服務層中的這種情況? – gipinani

+2

,因爲如果我可以在存儲庫層上處理這個問題,則不需要實現額外的服務或Daos。 –

回答

5

對於修改查詢,您需要將@Modifying添加到該方法。

確保你知道你選擇了這種方法的副作用:

  • 執行的操縱查詢幾乎繞過所有EntityManager緩存。因此,如果EntityManager已經加載它,後續的findOne(…)可能會/仍然會返回您試圖刪除的對象的舊實例。爲防止出現這種情況,請將@Modifying中的clearAutomatically標誌設置爲true,但請注意,這會導致所有掛起的更改都被清除。
  • 對於基於查詢的數據操作生命週期回調將被觸發並且級聯將在持久化上下文的級別上被觸發。這意味着,收聽​​事件的實體聽衆將不會收到通知。還有任何級聯操作