2011-03-24 83 views
1

我一直在理解如何在休眠中管理列表。休眠如何從列表中刪除項目

我看了以下帖子:hibernate removing item from a list does not persist,但沒有幫助。

因此,這裏的家長:

public class Material extends MappedModel implements Serializable 
{ 
    /** 
    * List of material attributes associated with the given material 
    */ 
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 
    @JoinColumn(name = "material_id", nullable = false) 
    @org.hibernate.annotations.IndexColumn(name = "seq_number", base = 0) 
    private List<MaterialAttribute> materialAttributes = new ArrayList<MaterialAttribute>(); 

這裏是孩子

公共類MaterialAttribute擴展MappedModel實現Serializable

{ 
    /** 
    * identifies the material that these attributes are associated with 
    */ 
    @ManyToOne 
    @JoinColumn(name = "material_id", nullable=false, updatable=false, insertable=false) 
    private Material material; 

所以在我的服務類我做了以下內容:

public void save(MaterialCommand pCmd) 
{ 
Material material = new Material(); 
if(null != pCmd.getMaterialId()) 
{ 
    material = this.loadMaterial(pCmd.getMaterialId()); 
} 

material.setName(pCmd.getName()); 
material.getMaterialAttributes().clear(); 

    List<MaterialAttribute> attribs = new ArrayList<MaterialAttribute>(); 
    if(CollectionUtils.isNotEmpty(pCmd.getAttribs())) 
    { 
     Iterator<MaterialAttributeCommand> iter = pCmd.getAttribs().iterator(); 
     while(iter.hasNext()) 
     { 
MaterialAttributeCommand attribCmd = (MaterialAttributeCommand) iter.next(); 
      if (StringUtils.isNotBlank(attribCmd.getDisplayName())) 
{ 
     MaterialAttribute attrib = new MaterialAttribute(); 
     attrib.setDisplayName(attribCmd.getDisplayName()); 
     attrib.setValidationType(null); 
     attribs.add(attrib); 
} 
     } 
    } 

    material.setMaterialAttributes(attribs); 
    this.getMaterialDao().update(material); 
} 

因此,在上面第一次創建數據庫時,正確地創建了一切。第二次,我的期望是集合中的第一組項目將被刪除,只有新項目將在數據庫中。那沒有發生。子項中的原始項目與新項目一起存在,並且seq編號從0開始。

而且,我看到下面的錯誤

org.hibernate.HibernateException:與級聯集合=「全刪除,孤兒」由所擁有的實體實例不再被引用:

上午什麼我想念。

回答

4

DELETE_ORPHAN的實施對收集操作應用了一些限制。特別是,您不應該用另一個集合實例替換該集合。相反,將新項目添加到現有集合中:

material.getMaterialAttributes().clear(); 
... 
material.getMaterialAttributes().addAll(attribs); 
+0

這樣做 - 將需要審查以確保我有充分的理解。 – boyd4715 2011-03-24 20:27:27