Вот моя ситуация: я загружаю объект, содержащий двунаправленные родительские отношения с дочерними элементами в мою базу данных. Позже этот объект загружается в мой пользовательский интерфейс, где могут быть сделаны изменения, в том числе удаление любого числа дочерних элементов из дочернего набора. Затем эта модифицированная копия моего объекта загружается с использованием метода saveOrUpdate. Однако, когда эта измененная копия сохраняется, все удаленные дети остаются в базе данных (новые дети, добавленные в набор, отлично работают). Во время этого процесса ошибок не возникает, но мне нужны эти удаленные дочерние элементы для фактического удаления из базы данных. Я вставил соответствующие части моего спящего и java-кода ниже.Hibernate не может удалить ребенка из базы данных
Родитель зимуют конфигурации:
<bag name="specimenTypes" table="masterPkSpecimenType" cascade="all-delete-orphan" inverse="true">
<key column="runid"/>
<one-to-many class="SpecimenType"/>
</bag>
ребенка в спящий режим конфигурации:
<many-to-one name="reportCriteriaBean" class="ReportCriteriaBean" column="runid" not-null="true" />
Код объекта Родитель:
public List<SpecimenType> getSpecimenTypes() {
return specimenTypes;
}
public void setSpecimenTypes(List<SpecimenType> specimenTypes) {
this.specimenTypes = specimenTypes;
if(this.specimenTypes != null){
for(SpecimenType specType : this.specimenTypes){
specType.setReportCriteriaBean(this);
}
}
}
Код объекта Ребенок:
public ReportCriteriaBean getReportCriteriaBean() {
return reportCriteriaBean;
}
public void setReportCriteriaBean(ReportCriteriaBean reportCriteriaBean) {
this.reportCriteriaBean = reportCriteriaBean;
}
EDIT:
Видимо моя проблема связана с явным вызовом setSpecimenTypes() после того, как я получить родительский объект из БД, и, прежде чем я сохранить обновленный объект обратно. причина, по которой я это делаю, заключается в том, что из-за некоторого динамического связывания списков мне нужен Список, который должен быть конкретной реализацией List (в частности, LazyList от Apache), когда он представлен в пользовательском интерфейсе. Однако, когда объект извлекается из БД, он не реализован таким образом, поэтому я создаю копию LazyList обычного списка, который был вытащен из базы данных, и вызвал setSpecimenTypes(), чтобы заменить его на мой недавно заполненный LazyList. Кто-нибудь знает, как мне это сделать?
Я вызываю setSpecimenTypes(), прежде чем обновлять объект (по причинам, которые я изложил в обновлении моего сообщения), я не понимаю, почему это имеет значение. Не следует ли обновлять список дочерних элементов, чтобы отражать то, что содержит текущий набор дочерних элементов, тем самым удаляя записи старых дочерних элементов? – TimmyJ
Спасибо за помощь. У меня все еще есть проблема.Когда я сменил геттер, чтобы вернуть украшенный список, я получаю следующую ошибку, когда родительский класс извлекается из БД: Коллекция с cascade = "all-delete-orphan" больше не ссылалась на экземпляр объекта-владельца. Я уверен, что setSpecimenTypes никогда не вызывается (я зашел так далеко, чтобы сделать его закрытым). Вы упомянули выше, что я должен создать * другой * getter, а не заменить текущий, как я. Есть ли причина, по которой мой путь был бы неправильным? – TimmyJ
Проблема с возвратом украшенного списка из существующего геттера заключается в том, что он больше не является Hibernate PersistentList. Hibernate не знает, что вы его завернули (или как развернуть) - он просто видит, что PersistentList, который был там, теперь ушел - отсюда исключение. Вам действительно нужен другой getter, но если ваш код зависит от 'getSpecimenTypes()', вы можете сделать private 'getSpecimentTypesDB()' и отобразить его в Hibernate. Я лично предпочитаю украшать компоненты пользовательского интерфейса, а не бизнес-объекты, но каждый из них имеет свое место. – ChssPly76