Hibernate cascade = "all-delete-orphan", не удаляет сирот - PullRequest
1 голос
/ 08 сентября 2011

У меня возникают проблемы при удалении потерянных узлов с использованием 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 и Джексона длясделать отображение JSON в Hibernate Class

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


ПРИМЕЧАНИЕ:

seizureObj имеет только две NEW записив его substanceIdentifieds Set.

Свойство id seizureObj установлено на существующую запись в БД.Но когда я вызываю saveOrUpdate, существующие записи (сироты) не удаляются.



Служба захвата использует Spring 10 * *

getHibernateTemplate.saveOrUpdate

Я читал темы о

JPA CascadeType.ALL не удаляет сирот
Спящий режим удаляет сирот при обновлении коллекции

Кажется, мои настройки верны.

Нужно ли

  1. загружать соответствующий объект из БД в фиктивный объект-объект сначала (с идентификатором, который имеет мой десериализованный объект)
  2. удалить ссылки на другой объект
  3. сохранить изменения
  4. обновить с моим десериализованным объектом

?

Ответы [ 2 ]

1 голос
/ 15 сентября 2011

На самом деле это можно сделать без вызова clear.

Все, что мне нужно было сделать, это вызвать правильную функцию.

использовать HibernateDaoSupport.getHibernateTemplate().merge(object)

В моем кодеСначала я проверяю, имеет ли десериализованный объект от Джексона прикрепленный идентификатор

, если это так, я вызываю сохранение, если нет, я вызываю слияние.

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

и функция слияния моего DAO:определяется следующим образом.

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

Это удаляет сирот, как это должно быть.

Если кто-то сталкивается с той же проблемой, не стесняйтесь, я открыт, чтобы помочь вам с этим.

С уважением, JS

1 голос
/ 14 сентября 2011

Вы должны загрузить исходный объект из БД с вашим идентификатором объекта, а затем очистить substanceIdentifieds, вызвав .clear(). Затем добавьте свои новые записи в тот же список, чтобы эти сироты были удалены. Потому что, когда вы загружаете объект из БД, в зависимости от класса вашей коллекции hibernate будет использовать org.hibernate.collection.AbstractPersistentCollection классы реализации в качестве классов-оболочек для вашей коллекции, чьи методы отслеживают изменения коллекции в контексте постоянства. Это означает, что ваши методы .remove() или .clear() идентифицируют объект, который необходимо удалить из БД, когда изменения объекта сохранены / сброшены.

...