2014-01-17 90 views
15

從書臨EJB3 JPA:在Java EE應用程序合併VS找到更新實體JPA

來處理最常見的策略本(-update實體 - )使用JPA是將結果的變化爲分離的實體實例,併合並未決的改變成一個持久性上下文,以便它們可以被寫入到數據庫

實施例: EMP參數是一個分離ë ntity

@Stateless 
public class EmployeeServiceBean { 
    @PersistenceContext 
    EmtityManager em; 

    public void updateEmployee(Employee emp){ 
     if(em.find(Employee.class, emp.getId()) == null){ 
      throw new IllegalArgumentException("Unknown Employee id") 
     } 

     em.merge(emp); 
    } 
} 

然後說:

如果信息被udated量是非常小的,我們能避免分離的對象,並通過定位託管版本和手動複製合併()操作完全進入它的變化。

例子: 這裏EMP連接

public void updateEmployee(int id, String newName, long newSalary) { 
    Employee emp = em.find(Employee.class, id); 
    if(emp==null){ 
     throw new IllegalArgumentException("Unknown Employee id") 
    } 
    emp.setEmpName(newName); 
    emp.setSalary(newSalary); 
} 

所以,看起來像小的更新和創建操作策略find(),然後設置新值逐一方便。但是,對於大數據更新(即集合),最好有一個分離的實體和它的所有關係(與CascadeType.Merge)並且做一個大的merge()

好的,但是爲什麼

+0

數據庫訪問對於較大的對象來說是很昂貴的,因此它應該在分離模式下完成,以確保您不會對後端進行不必要的調用。 – hd1

+0

而不是「emp.setEmpName(newName);」逐個設置字段。可以通過「emp = new Employee(//設置字段)」來完成嗎? @請讓我出來 –

+0

是的,實際上setter/getters是規範可選的,你可以在構造函數上初始化參數或者使用流利的API,JPA會找到這些值。謹慎使用它;) – Sergio

回答

11

因爲如果你的bean有很多屬性,JPA將在合併過程中逐個檢查所有屬性,如果你正在處理一個分離的對象。現在,如果你有一個200個atrributes並且只想改變1個字段的bean,那麼JPA更容易獲得託管版本(在內部,JPA知道何時管理實體的一個字段是「髒的」或者不),那麼它只會處理那個特定的屬性。

+2

顯然這是依賴於實現的。某些JPA實現(例如DataNucleus JPA)使用字節碼增強並添加一個字段,用於存儲持久字段是否在分離時被修改,因此attach(合併)過程非常高效。 – DataNucleus

+0

如果我反思修改實體的字段(從而繞過方面/字節碼增強),那該怎麼辦?從DataNucleus和Hibernate JPA的角度來看? –