Hibernate cascade =“all-delete-orphan”,不删除孤儿

时间:2011-09-08 16:38:26

标签: hibernate spring-mvc jackson cascading-deletes

我无法使用Hibernate删除孤立节点,并使用以下映射

@OneToMany(fetch = FetchType.LAZY, mappedBy = "seizure",orphanRemoval=true)
@JsonManagedReference  
@Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
public Set<SubstanceIdentified> getSubstanceIdentifieds() {
    return this.substanceIdentifieds;
}

.hbm.xml映射就像这样

  <set name="substanceIdentifieds" table="substance_identified" inverse="true" lazy="true" fetch="select" cascade="all-delete-orphan">
        <key>
            <column name="seizure_id"  not-null="true" />
        </key>
        <one-to-many class="org.unodc.incbszdb.db.base.SubstanceIdentified" />
    </set>

我使用Spring MVC和Jackson来执行JSON到Hibernate类映射

 @RequestMapping(value = { "/save.json" }, method = RequestMethod.POST)
 public ModelMap save(@RequestBody Seizure seizureObj, Model model) {
    seizureService.saveOrUpdate(seizureObj);


注意:

seizureObj在其substanceIdentifieds集中只有两个 NEW 条目。

seizureObj的id属性设置为db中的现有记录。但是,当我调用saveOrUpdate时,现有记录(孤儿)不会被删除。



Seizure Service使用Spring的

getHibernateTemplate.saveOrUpdate

我已阅读有关

的主题

JPA CascadeType.ALL does not delete orphans
Hibernate deleting orphans when updating collection

看来我的设置是正确的。

我必须

  1. 首先从虚拟对象对象中的DB加载相应对象(使用我的反序列化对象的ID)
  2. 删除对其他对象的引用
  3. 保存更改
  4. 使用我的反序列化对象进行更新

2 个答案:

答案 0 :(得分:1)

您应该使用对象ID从DB加载原始对象,然后通过调用substanceIdentifieds清除.clear()。然后将新条目添加到同一列表中,以便删除那些孤儿。因为当您从DB加载对象时,基于您的集合类,hibernate将使用org.hibernate.collection.AbstractPersistentCollection实现类作为集合的包装类,其方法监视持久化上下文中的集合更改。这意味着您的.remove().clear()方法可识别在保存/刷新对象更改时需要从DB中删除的对象。

答案 1 :(得分:1)

在没有打电话的情况下,可以这样做。

我所要做的就是调用正确的功能。

使用HibernateDaoSupport.getHibernateTemplate().merge(object)

在我的代码中,我首先测试来自jackson的反序列化对象 已附上身份证件

如果是的话,我会调用save,如果不是,我会调用merge。

if(obj.getId()){
   myDAO.save(obj);
}else{
   myDAO.merge(obj);
}

我的DAO的合并功能就是这样定义的。

public void merge(E transientObject) {
  getHibernateTemplate().merge(transientObject);
}

这会删除应该是的孤儿。

如果有人面临同样的问题,请不要犹豫,我愿意为您提供帮助。

问候JS