Hibernate - Как каскадно удалять удаленные объекты - PullRequest
2 голосов
/ 11 августа 2009

У меня есть спящий объект, который отсоединяется и переносится в толстый Java-клиент Swing с помощью EJB. Затем объект каким-то образом модифицируется и возвращается на сервер, где сервер затем обновляет измененный объект в базе данных. Все работает хорошо для свойств, которые меняются, но у меня проблема с тем, как удалить отображение many-to-one.

Например, с учетом следующего сопоставления:

<hibernate-mapping>
<class name="com.wg.common.bean.Patient" table="patient">
    <id name="id" type="integer">
        <column name="id" />
        <generator class="sequence">
            <param name="sequence">patient_id_seq</param>
        </generator>
    </id>
    <many-to-one name="address" class="com.wg.common.bean.Address" cascade="all">
        <column name="address_id" />
    </many-to-one>
    ...

Скажем, у меня есть объект пациента, который отправлен клиенту. Пользователь ранее добавил адрес. На каждого пациента может быть только один адрес. На клиенте, если пользователь удаляет адрес, я вызываю setAddress(null) на объекте пациента, прежде чем вернуться на сервер. Когда я добираюсь до сервера, он сохраняет поле address_id как ноль, но оставляет запись адреса в базе данных. Я понимаю, почему он это делает. Я ломаю только один конец отношений. Предпочтительно, я бы использовал delete-orphan. Однако, согласно документации Hibernate, delete-orphan недоступно для many-to-one отображений. Правильная процедура для вызова на сервере (псевдокод):

Address address = patient.getAddress();
session.delete(address);
patient.setAddress(null);

Проблема с этим шаблоном заключается в том, что если я хочу придерживаться процесса простой передачи обратно объекта Patient, который я хочу сохранить, у меня нет возможности узнать, есть ли у него адрес, который необходимо удалить. Я должен сделать несколько менее элегантных обходных путей, чтобы решить эту проблему, например, запросить базу данных, чтобы узнать, был ли адрес, и удалить его, если он является нулевым в переданном объекте, или создать setDeleteAddress(boolean), getDeleteAddress() методы. в классе пациента и настройте их на стороне клиента, если пользователь хочет удалить адрес.

Другая альтернатива - сделать связь «один ко многим» между пациентом и адресом. Тогда я мог бы использовать delete-orphan. Однако, поскольку это действительно взаимно-однозначное отношение, мне нужно было бы поместить в класс Patient сумасшедший метод получения / установки, чтобы я не засорял свой код ссылками на коллекцию, когда на самом деле коллекции нет:

public Address getAddress() {
    if(addresses != null && addresses.size() > 0) return addresses.get(0);
    else return null;
}

Есть ли лучший способ решить эту проблему? Как вы справились с удалением сущности на обособленных объектах?

Ответы [ 3 ]

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

Кажется, я вспоминаю, что на самом деле в некоторых случаях можно сопоставить однозначные отношения с одним свойством. Я не могу это проверить, но в документации есть некоторые советы .

В качестве альтернативы внешний ключ с уникальным ограничением от Сотрудника к Человеку может быть выражен как:

<many-to-one name="person" class="Person" column="PERSON_ID" unique="true"/>

Эту ассоциацию можно сделать двунаправленной, добавив в отображение Person следующее:

<one-to-one name="employee" class="Employee" property-ref="person"/>

Возможно, вам придется немного повозиться и добавить cascade="delete" к сопоставлению один-к-одному. Я никогда не пробовал это сам. Лучшая альтернатива - ответ ChssPly76, если у вас есть контроль над схемой базы данных.

0 голосов
/ 10 сентября 2009

В итоге я просто создал deleteFlag в классе Address, чтобы указать EJB, что рассматриваемый Address должен быть удален из Patient.

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

Адрес сопоставления как many-to-one, кажется, корень ваших проблем. Адрес является «родителем» в таких отношениях, что не имеет большого смысла. Подумайте о том, чтобы сопоставить его как компонент или вместо этого. Никакая коллекция не должна быть вовлечена в любом случае.

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