开发者

Hibernate cascade="all-delete-orphan", doesn't delete orphans

I am having trouble deleting orphan nodes using Hibernate with the following mapping

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

the .hbm.xml mapping is like this

  <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" />
    &开发者_运维知识库lt;/set>

I use Spring MVC and Jackson to do the JSON to Hibernate Class mapping

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

NOTE:

seizureObj has only two NEW entries in its substanceIdentifieds Set.

The id property of seizureObj is set to an existing record in the db. But when I call saveOrUpdate existing records (orphans) don't get deleted.

Seizure Service uses Spring's

getHibernateTemplate.saveOrUpdate

I have read the threads about

JPA CascadeType.ALL does not delete orphans

Hibernate deleting orphans when updating collection

It seems my setup is right.

Do I have to

  1. load the according object from the DB in a dummy object object first (with the ID my de-serialized object has)
  2. delete the references to other object
  3. save the changes
  4. update with my de-serialized object

?


Acutally it is possible to do it without calling clear.

All I had to do is calling the right function.

use HibernateDaoSupport.getHibernateTemplate().merge(object)

In my code I first test if the de-serialized object from jackson has a ID attached

if so I call save, if not I call merge.

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

and the merge function of my DAO is defined like this.

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

This deletes the orphans like it is supposed to be.

If somebody is facing the same problem do not hesitate, I am open to help you with it.

Regards JS


You should load original object from DB with your object ID, then clear the substanceIdentifieds by calling .clear() on it. Then add your new entries to the same list, so those orphans would get deleted. Because when you load object from DB, based on your collection class hibernate will use org.hibernate.collection.AbstractPersistentCollection implementation classes as wrapper classes for your collection, whose methods monitors collection changes in persistence context. That means your .remove() or .clear() methods identifies the object that needs to be removed from DB when object changes are saved/flushed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜