Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> hibernate пометить запись удаленной, но не удалять 
:(
    Опции темы
Samotnik
Дата 14.10.2010, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 8
Всего: 191



Привет.
Нужно реализовать САБЖ. Т.е. при удалении не удалять поле, а просто выставлять некий boolean флаг в true(что означает, что запись удалена)
т.е. порще говоря, в методе для удаления я вместо привычного session.delete(object) вызываю просто сеттер для флага, т.е. object.setRemove(true)
Вроде все хорошо smile Но появилась проблема - в этой таблице присутствует поле из другой таблицы, которые связаны связью.
Вот таблица (Men), в которой присутствует поле из другой таблицы (Device)

Код

public class Men {
        @Id
    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "device_id")
    private Device device; 

//..... 

А вот маппинг Device
Код

public class Device {
    @Id
    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @OneToMany(mappedBy = "device", cascade = {CascadeType.REMOVE}, fetch = FetchType.EAGER)
    private Set<Men> men;


Получается, что при удалении device, у меня не явно удаляется и men, а я хочу этого избежать. Мне нельзя удалять men физически, а просто помечать что он удален.
Какой есть выход из положения ? 

PM MAIL   Вверх
carper
Дата 14.10.2010, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 2.3.2005

Репутация: 1
Всего: 8



Samotnik
Если в таблице men есть ссылка на поле из таблицы device, то удалить данные из device, оставив висящую ссылку на это поле в men можно только если делать поле device_id в men необязательным и писать туда null.

Но тогда получается, что удаление из таблицы device не стоит описывать через CascadeType.REMOVE (не говоря уж о том, что во многих СУБД это гораздо проще и логичней задается еще на этапе создания таблиц), а надо написать соотв. триггер/процедуру в базе, либо производить удаление в java методе, которые и позаботятся о замене device_id на null и пометке записи.

Hibernate не настолько умен, чтобы автоматически догадаться о вашей хитрой операции.
Для этого, и тысячи других, случаев и пишутся классы, реализующие DAO, которые и занимаются особенностями CRUD.

У вас вообще какой-то странный случай, когда таблица men как-бы настолько зависит от device, что записи в ней должны помечаться как удаленные, а с другой удаляться не должны.
Нет, приблизительно о целях догадаться можно, но обычно для этого существуют более "правильные" способы. 

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

PM MAIL   Вверх
Samotnik
Дата 14.10.2010, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 8
Всего: 191



Цитата(carper @  14.10.2010,  16:53 Найти цитируемый пост)
я стараюсь вообще избегать автоматического каскадного удаления

Эти слова уже не первый человек говорит. Неужели все так плохо. smile

Тут идея вся в чем. 
Есть таблица (людей) которые подписываются на новость, и в этой таблице есть поле, которое приходит из другой таблицы по связи (пример я уже давал). Есть возможность добавления/удаления/редактирования людей. Но удалять не хочется, потому что нужно оставить для статитстики, например, кто за пол года удалился, присоединился, и в какое время. А если тупо удалять, после того как человек отписывается, то статитиски никакой не будет. А это плохо.

PM MAIL   Вверх
carper
Дата 15.10.2010, 08:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 2.3.2005

Репутация: 1
Всего: 8



Samotnik,
Вы бы тогда пояснили, что лежит в device_id и какой объем информации предполагается хранить в men, а то с ходу придумывается сразу два решения - денормализация men по device_id или отдельная таблица для статистики, опять же, или совсем без device_id или с денормализованным значением.


"Эти слова уже не первый человек говорит. Неужели все так плохо."

Ну как вам сказать, это все равно как спор нужен ли нормальный генератор экранных форм в JAVA?

Для quick and dirty решений несомненно нужен и очень обидно, что сообщество JAVA долгое время почему-то полагало совсем иначе, да и сейчас не все так гладко, по крайней мере те генераторы, что  я видел (а видел я их мало, так что, возможно, не прав) хуже чем в Delphi 2.

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

Опять же, для большинства нормальных СУБД для каскадного удаления Hibernate и нафиг не нужен.

В Hibernate вообще часть решений связана с тем чтобы обеспечить универсальность в тех областях, которые на практике нужны 0,01% разработчиков, да и тем неясно зачем.

Например, Oracle, Ms SQL, DB2, MySQL (InnoDB), Firebird, Interbase, PostgreSQ, Apach Derby, Cloudscape, думаю при желании можно вспомнить еще десяток, поддерживают ON DELETE CASCADE "из коробки", причем это решение принимается на этапе создания архитектуры и для этого не надо загаживать JAVA код не нужными аннотациями.

Hibernate хорош там, где надо отобразить плоские реляционные таблицы на объекты, во всем остальном для проектов всерьез использующих работу с СУБД, надо быть очень осторожным, полагаясь на его услуги, но могут оказаться медвежьими. smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0795 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.