2013-06-18 137 views
1

我試圖做一個非常簡單的刪除操作,但不知何故,它不工作,因爲我更新DAO到JpaRepository。基本上它是這樣的:JpaRepository刪除子元素

A a = aRepository.findOne(id); 
a.setSomeField("someNewString"); 

List<B> bList = a.getBs(); 
bList.clear(); 
aRepository.saveAndFlush(a); 

現場獲取的更新預期,但bList保持不變。我甚至已經試過:

A a = aRepository.findOne(id); 
a.setSomeField("someNewString"); 

List<B> bList = a.getBs(); 
for(B b : bList) { 
    bRepository.delete(b); 
} 
bRepository.flush(); 
bList.clear(); 
aRepository.saveAndFlush(a); 

還是一樣......

A類看起來是這樣的:

@Entity 
@Table(name = "A") 
public class A implements Serializable { 
    private static final long serialVersionUID = -1286451120913657028L; 

    @Column(name = "id", length = 16, nullable = false, updatable = false) 
    @GenericGenerator(name = "uuid", strategy = "uuid2") 
    @GeneratedValue(generator = "uuid") 
    @Basic(fetch = FetchType.EAGER) 
    @Id 
    protected UUID id; 

    @OneToMany(mappedBy = "a", fetch = FetchType.EAGER) 
    @Cascade({ CascadeType.ALL }) 
    List<B> bList; 

    // getter + setter 
} 

我在做什麼錯?


B類:

@Entity 
@Table(name = "B") 
public class B implements Serializable { 
    @Column(name = "id", length = 16, nullable = false, updatable = false) 
    @GenericGenerator(name = "uuid", strategy = "uuid2") 
    @GeneratedValue(generator = "uuid") 
    @Basic(fetch = FetchType.EAGER) 
    @Id 
    protected UUID id; 

    @ManyToOne(optional = false) 
    @JoinColumns({ @JoinColumn(name = "A_id", referencedColumnName = "id", nullable = false) }) 
    @Valid 
    A a; 

    // setter + getter 
} 

getter和setter方法都一樣簡單possbile:

public List<B> getBList() { 
    return bList; 
} 

public void setBList(List<B> bList) { 
    this.bList = bList; 
} 

一些詳細信息:

  • 春天3.2.2
  • 冬眠4.2.2
  • 彈簧數據公地1.5.1
  • 彈簧數據的JPA 1.3.2
+0

B類是什麼樣的?和A.getBs()方法? – Spiff

+0

更新了最初的發佈。 –

回答

6

更新A.bList屬性,如下所示:

public class A { 
    @OneToMany(mappedBy = "a", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) 
    List<B> bList; 
} 

orphanRemoval = true註釋屬性將告訴底層JPA實現刪除沒有任何父級的B記錄。

另外,由於B方管理關聯,所以在中斷關係時應清除其a屬性。爲了使這更易於閱讀,並從主叫去除這樣的實現細節的負擔,就應該引進的管理方法A

public class A { 
    public void clearBList() { 
     for (B b : bList) { 
      b.releaseA(); 
     } 
     bList.clear(); 
    } 
} 

public class B { 
    void releaseA() { 
     this.a = null; 
    } 
} 

你應該避免直接暴露集合,而是返回它的一個不可改變的版本,以防止客戶到A類直接修改集合而沒有A類知道它。 A管理B列表,所以它應該完全控制它!

public class A { 
    public List<B> getBList() { 
     return Collections.unmodifiableList(bList); 
    } 
} 

希望有幫助。

+0

謝謝你!我現在得到它的工作:我已經把'CascadeType.ALL'放在'@ OneToMany'註釋中。在我**之前**使用來自休眠的'@ Cascade'註釋。現在我將保留兩個註釋。我還加了'orphanRemoval = true'。清除列表'a.getBList()。clear(); aRepository.saveAndFlush(a);'就夠了。 :) –