Hibernate не может удалить ребенка из базы данных - PullRequest
1 голос
/ 06 августа 2009

Вот моя ситуация: я загружаю объект, который содержит двунаправленные родительские дочерние отношения в мою базу данных. Позже этот объект загружается в мой пользовательский интерфейс, где можно вносить изменения, включая удаление любого числа дочерних элементов из дочернего набора. Эта измененная копия моего объекта затем загружается с помощью метода saveOrUpdate. Однако при сохранении этой измененной копии все удаленные дочерние элементы остаются в базе данных (новые дочерние элементы, добавляемые в набор, работают нормально). В течение этого процесса не выдается никаких ошибок, но мне нужно, чтобы эти удаленные потомки действительно были удалены из базы данных. Я вставил соответствующие части моего спящего и java-кода ниже.

Конфигурация родительского режима гибернации:

<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, мне нужно, чтобы List был конкретной реализацией List (в частности, LazyList apache), когда он представлен в пользовательском интерфейсе. Однако, когда объект извлекается из БД, он не реализуется таким образом, поэтому я создаю копию LazyList обычного List, который был извлечен из базы данных, и вызываю setSpecimenTypes (), чтобы заменить его новым заполненным LazyList. Кто-нибудь знает, как мне это сделать?

1 Ответ

0 голосов
/ 06 августа 2009

Ваше отображение выглядит правильно. Как вы убираете детей? Что-то похожее на getSpecimenTypes().remove(X) или у вас есть специальный метод для этого (если да, вы можете опубликовать это)?

Кроме того, когда ваш родительский объект переносится на уровень пользовательского интерфейса и обратно - выполняется ли это в одном сеансе? Вы уверены, что никто не сбрасывает коллекцию детей, вызывая setSpecimenTypes() где-то посередине?

Обновление (на основе разъяснений):

Сброс specimenTypes определенно является проблемой. Как Hibernate узнает, что вы удалили определенный элемент? Удаления отслеживаются в собственном PersistentList Hibernate, который упаковывает ваш список при загрузке родительского объекта.

LazyList (я предполагаю, что вы имеете в виду тот, что из Commons Collections) является декоратором, поэтому вы можете создать другой метод getter в пределах вашего родительского объекта, который бы обернул вашу коллекцию specimenTypes в LazyList и вернул ее (кэшируя в переменная-член для эффективности при повторных попытках доступа).

Суть в том, что вы никогда не должны перезаписывать коллекцию, управляемую Hibernate, своей собственной версией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...