| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Hibernate & cascade DELETE |
| Автор: MisterCleric 13.7.2009, 17:18 | ||||||||||||
| Привет, ребята. выручайте теперь и меня. В обще есть у меня такая структура. Пусть простит меня Заказчик! Но блин, надо срочно. Вот такие сущности: (сначала покажу, что есть потом скажу в чем трабла)
Т.е.: Каждый "банк" имеет список "программ страхования на банк". Каждая "программа страхования на банк" имеет список "групп рисков в программе страхования на банк". Каждая "группа рисков в программе страхования на банк" имеет список настроек. Проблема возникает, когда я настраиваю список "группа рисков в программе страхования на банк": могу добавить новую, могу убрать те что были. Все сохранения в базе вызываю на коренной сущности - Bank методом EntityManager.merge Естественно добавление прокатывает нормально: везде проставил соответствующие ИД и произошел INSERT. А вот когда я из списка убираю группу рисков, то вылазит такая беда:
что для меня не есть логично. Я-то могу убрать констрейнты, но это ж фигня выйдет: полна таблица NULL'ов и никаких удалений. Когда у меня было простое тернарное соединение без пожелания заказчика добавить к нему настройки было так:
Естественно все работало. Понимаю, что где-то проблема на композитном ключе. Но как ее побороть, блин, что бы при мерже коренной сущности корректно грохались сущности из вложенной коллекции. Да, еще было такое:
Тоже, когда пытался JPA-возможностями воспользоваться:
Тоже выдавал подобную фигню в стиле:
Как быть? помогите |
| Автор: Evgeni68 13.7.2009, 23:10 |
| Может быть я не до конца понял проблему. При работе с Hibernate пользуюсь только xml-маппингом, так вот удаление сущности из БД при удалении ее из коллекции родительской сущности, позволяет только указание типа каскадности: cascde="all, delete-orphan". Вроде бы есть аннотация CascadeType.DELETE_ORPHAN. Возможно комбинация ALL и DELETE_ORPHAN поможет. Плюс, непонятно как связаны сущности RiskGroup и BankInsuranceschemeRiskGroup. Если RiskGroup содержит коллекцию BankInsuranceschemeRiskGroup, то с какой стати BankInsuranceschemeRiskGroup должна удалиться. |
| Автор: MisterCleric 13.7.2009, 23:25 | ||||
Обязательно должна удалиться! Так как RiskGroup - это справочник. А если мы что-то убираем из спавочника, то все что с ним связанно должно подохнуть. Так как все остальные страховые дела потом идут через нее. Раньше были настройки на уровне этого справочника на всю систему одни настройки на одну группу рисков. а теперь заказчик захотел что бы группа рисков была одна, а настройки были на уровне конкретной программы в конкретном банке
Спасибо. попробую. Еще мой DBA предложил сделать нормализацию: убрать везде композитные ключи и навешать сиквенсов и форинг кеев. Но это уже будем пробовать завтра. Тут я сто пудово уверен, что получится. Но столько придеться переписывать.... |
| Автор: DimW 14.7.2009, 10:29 | ||||||
MisterCleric, констрайнты тут не причем просто поле BANKID создано как not null. удаление foreign key -ев не решит проблему.
на мой взгляд не совсем логично. если рыссматривать проблему некоректно введенных данных в справочник то да, удаление необходимо. если рассматривать ситуацию что с какого то времени позиция в RiskGroup должна прекратить свое действие то правельней будет проставить дату закрытия и предусмотреть это в запросах. что касается каскадного удаления то это можно предусмотреть при создании foreign key:
т.е. on delete cascade вам обеспечит каскадное удаление позиций в сущностях при удалении связанной позиции в справочнике(но дата завершения всеравно понятней и логичней и дает возможность заглянуть в прошлое |
| Автор: MisterCleric 14.7.2009, 11:00 | ||
Мне удалять каскадом из настроечной таблицы при удалении пока не надо. Просто надо удалить из таблицы настроек, если я удалю из кллекции этих настроек, а сохраню сущность которая содержит эту коллекцию |
| Автор: DimW 14.7.2009, 11:29 | ||
иными словами вы пытаетесь удалить позицию справочника и оставить на нее ссылку в другой таблице? ссылку на идентификатор которого нет??? |
| Автор: MisterCleric 14.7.2009, 11:42 | ||
Такой ссылки нету. Есть сущность "Программа страхования" у нее есть коллекция "Группы рисков". Вот в эту коллекцию я добавляю и убираю из нее элементы одним махом. потом сохраняю эту "Программа страхования". Вложенная коллекция должна выполнить соответствующие операции по инсерту и делиту, а если надо и апдейту - так как пользователь может поменять какие-то настройки в конкретной группе рисков. Вся загвоздка в том, что у меня композитные ключи. В общем я тут что-то понаписывал, счас тестирую: вроде заработало. Будет работать четко опишу, что вышло |
| Автор: DimW 14.7.2009, 11:54 | ||
что мне подсказывает что трабла не в составных ключах.
"Группы рисков" относятся еще к какой нить сущности? |
| Автор: MisterCleric 14.7.2009, 12:10 | ||||
В общем, решилось быстро так:
Т.е. устроил в сущоности из коллекции ссылку на ту сущность о которой она зависит. А в коренной сущность указал bidirection/ Приходиться правда кроме элементов композитного ключа указывать еще и форинг-сущность при добавлении в коллекцию. Естественно выходит, что формируется корректный DELETE FROM:
Так что делаем выводы: для корректной работы EntityManager надо везде где можно проставлять bidirection. Так же помогло DELETE_ORPHAN. Что оно такое почитаю. А Evgeni68 получает плюсик. Естественно, в дальнейшем надо сделать нормализацию базы. Но эт в моем случае можно. Так как я архитектор базы. Но есть другие базы, которые уже написаны и надо к ним прикручивать функционал на java. Вот там и помогут знания о каскадном удалении и компзитных ключах. Считаю тему закрытой. Всем спасибо за участие. Но естественно от советов не откажусь |