2016-08-11 325 views
8

我想如果它已經發現像數據庫中的條目知道,如果在CrudRepository{save}方法做一個更新:如果我叫上該方法春數據:CrudRepository的保存方法和更新

@Repository 
public interface ProjectDAO extends CrudRepository<Project, Integer> {} 

@Service 
public class ProjectServiceImpl { 

@Autowired private ProjectDAO pDAO; 

public void save(Project p) { pDAO.save(p); } } 

所以已經註冊的條目,它會更新它,如果它發現一個更改的屬性?

謝謝。

回答

8

我想,如果它已經在數據庫中查找

入門知道在CrudRepository的{保存}方法做一個更新 關於它的Spring文檔是不準確的:

保存給定的實體。爲保存操作可能已經完全改變了實體實例 使用返回的實例進行進一步操作 。

但隨着CrudRepository inteface好好嘗試提出與更新實體明確命名的另一種方法,我們可以假設,是因爲CRUD預計將完成所有的CRUD操作(創建,讀取,更新,刪除)。

這個假設是由SimpleJpaRepository 類是CrudRepository默認實現這表明,這兩種情況都通過該方法處理的執行證實:

@Transactional 
public <S extends T> S save(S entity) { 

    if (entityInformation.isNew(entity)) { 
     em.persist(entity); 
     return entity; 
    } else { 
     return em.merge(entity); 
    } 
} 

所以,如果我調用該方法上已經registred項,它會更新 它,如果它發現一個改變的屬性?

它將在這種情況下做一個合併操作。因此,所有字段都根據如何設置合併級聯和只讀選項進行更新。

+0

因此,如果像實體有複雜類型,讓我們說一個圖像,我認爲我需要用裸手來更新。 –

+0

你是什麼意思的形象?如果它不是一個jpa關係字段,它在任何情況下都會被更新。因此,如果該字段在要保存的實體中爲null,則它將在現有行中將其值覆蓋爲null。 – davidxxx

+0

明白了。另一件事,在這裏我看到'@Transactionel',所以我不需要將該註釋添加到服務類no? –

5

望着CrudRepository界面的默認implemantation

/* 
    * (non-Javadoc) 
    * @see org.springframework.data.repository.CrudRepository#save(java.lang.Object) 
    */ 
    @Transactional 
    public <S extends T> S save(S entity) { 

     if (entityInformation.isNew(entity)) { 
      em.persist(entity); 
      return entity; 
     } else { 
      return em.merge(entity); 
     } 
    } 

保存方法管理兩種情況:

- 如果人物ID爲空(創建一個新的實體)然後保存將調用persist方法= >插入查詢將被執行。

如果person id不爲空,那麼save將調用merge:從entityManagerFactory中獲取現有實體(如果它不存在,則從2級高速緩存中獲取,然後從數據庫中獲取),並將分離的實體與託管並最終通過調用update query將更改傳播到數據庫。

0

我想,如果它已經在數據庫中查找條目知道在CrudRepository的{保存}方法做一個更新:

答案是肯定的,它會更新,如果它發現一個條目:

從春天文檔:這裏https://docs.spring.io/spring-data/jpa/docs/1.5.0.RELEASE/reference/html/jpa.repositories.html

保存實體可以通過CrudRepository.save(...)-Method來執行。它將使用底層的JPA EntityManager持久化或合併給定的實體。如果實體沒有被持久化,Spring Data JPA將通過調用entityManager.persist(...)-Method來保存實體,否則將調用entityManager.merge(...)-Method。

0

準確地說,保存(OBJ)方法將把OBJ爲記錄,如果該ID爲空(因此將執行插入),並把OBJ作爲現有記錄如果ID填寫在(因此將做合併)。

爲什麼這很重要?

假設Project對象包含一個自動生成的ID和一個必須唯一的person_id。你創建一個Project對象並填入person_id但不是id,然後嘗試保存。 Hibernate會嘗試插入這條記錄,因爲id是空的,但是如果這個人已經存在於數據庫中,你將會得到一個重複的鍵異常。

如何處理
要麼做一個findByPersonId(ID)來檢查obj是在數據庫已經,並且從一旦發現,
或者只是嘗試保存獲得ID和捕獲異常在這種情況下,你知道它已經在數據庫中了,你需要在保存之前獲取並設置ID。