Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > удаление строки в таблице по id


Автор: sith 14.2.2008, 01:21
подскажите пожалуйста... я работаю с хибирнейтом - как удалить строку передав ему лишь ее ID.  Сейчас, как по мне, оно работатет не совсем логично... я сначала должен получить обьект строки которой хочу удалить... а потом лишь передать методу delete, его... можно ли проще... без предварительного обрщания в БД?

Автор: Kangaroo 14.2.2008, 01:37
Нельзя удалить по ID. Только достав объект из базы.
Вот почитай http://forum.hibernate.org/viewtopic.php?p=2364807&highlight=&sid=fc8eac3f32109119ed75a47290973464#2364807

Автор: necromancer 15.2.2008, 00:29
Если нужно просто и без затей удалить запись то можно воспользоватся:
SQLQuery q = session.createSQLQuery("delete from A where b=?");
q.setInteger(id);
q.execudeUpdate();

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

Автор: Kangaroo 15.2.2008, 00:36
Цитата(necromancer @  14.2.2008,  23:29 Найти цитируемый пост)
создать объект новый, присвоить ему айди и заставить хибернат удалить его. 

Хитро, но вроде не сработает  smile 

Автор: sith 15.2.2008, 11:27
поля обязательные для заполнения в таком варианте придеться все равно запонять... он выругается на это

Автор: pompei 15.2.2008, 11:46
Я вообще считаю, что любые ОРМы, в том числе и кибернет, изначально предполагают, что единицей действия является объект, т.е. предполагается, что какая-то работа с некой частью объекта не допустима: объект должен целиком загружаться и целиком сохранятся, ну и, по аналогии, целиком удаляться, т.е. достать объект целиком и удалить - это нормально.

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

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

Автор: iluvatar 15.2.2008, 11:48
а вариант, предложенный necromancer чем вас не устраивает? объект в таком случае загружаться не будет.

Автор: pompei 15.2.2008, 11:55

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

Автор: mindflyer 15.2.2008, 11:55
Цитата(sith @  14.2.2008,  01:21 Найти цитируемый пост)
Сейчас, как по мне, оно работатет не совсем логично

Цитата(necromancer @  15.2.2008,  00:29 Найти цитируемый пост)
создать объект новый, присвоить ему айди и заставить хибернат удалить его. 


А смысл? Хибернейт ведь не от хорошей жизни предпочитает подгрузку перед удалением - это сделано для того, чтобы можно было корректно отработать всякие каскадные действия при удалении, обновить кэш и прочее. 
В простейшем случае можно удалить SQL запросом. Но, если много связей между объектами, то лучше сначала загрузить объект и потом удалять его - в этом случае имеем гарантию сохранения согласованности данных и в бд и в кэше. Если быстродействие не удовлетворяет - можно поиграться с маппингом, там есть возможность задания каскадного удаления на уровне СУБД, но с некоторыми ограничениями (детально не разбирался). У нас так и сделано - везде удаление через предварительную подгрузку, в критичных местах - всякие ухищрения.


Автор: pompei 15.2.2008, 12:03
Я вообще считаю, что оптимизировать удаление не нужно - это достаточно редкая операция. В некоторых больших системах такой операции вообще нет, например, в тех, где ведётся история операций.

ЗЫ. "Оптимизировать во время реализации - вредно для здоровья" (С) Мартин Фаулер

Автор: mindflyer 15.2.2008, 13:09
Цитата(pompei @  15.2.2008,  12:03 Найти цитируемый пост)
Я вообще считаю, что оптимизировать удаление не нужно - это достаточно редкая операция. В некоторых больших системах такой операции вообще нет, например, в тех, где ведётся история операций.

Ситуации и большие системы бывают разные smile У нас в одном довольно частом use-case удаление стандартным способом длится почти 3 минуты. С ухищрениями - менее 30 секунд. История изменений у нас таки ведётся smile 
И это действие активируемое пользователем. А есть ещё массивные операции по расписанию - где удаляются и вставляются миллионы записей, естественно, здесь удаление идёт в обход хибернейта.

Автор: pompei 15.2.2008, 13:47
Выб не могли бы расказать о системе в общих чертах?

Автор: mindflyer 15.2.2008, 16:46
Цитата(pompei @  15.2.2008,  13:47 Найти цитируемый пост)
Вы не могли бы рассказать о системе в общих чертах?

Это не имеет отношения к теме, ну да ладно. ПО для туристических агенств/операторов. Откуда массивные операции удаления/вставки:
1) многие операторы предоставляют для ускорения доступа к своим продуктам (в частности, самолётам) файлы с описаниями (краткая информация, необходимая для поиска). Ежедневно выкладывают на ftp. Наша система также ежедневно забирает их и кладёт в локальную базу, для поисков. Записей каждый день несколько миллионов, их проще и быстрее все убивать и создавать новые, чем апдейтить существующие.
2) опять таки с целью ускорения поисков создаётся множество записей с пред рассчитанными ценами для всяких частных случаев - при изменениях в бизнесс-данных быстрее грохнуть старые и создать новые записи, нежели апдейтить существующие. Таких записей тоже миллионы, в перспективе - десятки и сотни миллионов.

На этапе поиска удобнее работать через хибернейт, при обновлении данных - голый SQL.

Автор: necromancer 17.2.2008, 20:48
вставлю и свои пять копеек =)
при использовании связей удаление через скл не оправдано. Хотя есть ньюанс. Предположим у нас огромное число записей и необходимо произвести обновление одного поля по опереденному параметру. Если под этот параметр попадает не много записей (относительно бд) то хибернейт справится нормально, а если их много? то вы представляете вытащить миллион записей и заапдейтить их обратно? хотя это можно сделать 1 скл запросом?. 
далее на момент работы хибернаты, необходимо поддерживать транзакционность. т.е. пока вы будете вытаскивать эти много записей, остальные клиенты должны курить в сторонке?

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

Личто мое мнение: ОРМ хорош когда нужно встаивть запись, иногда в простейших случаях получить обратно. удалить эту же запись.Чуть что более сложное не гнушайтесь использовать скл. 
Есть возражение что хибер не зависит от базы а скл зависит - брехня. Возьмите blob в Oracle и MySQL и как говорится почувствуйте разницу.

Добавлено через 2 минуты и 27 секунд
Цитата(pompei @  15.2.2008,  11:55 Найти цитируемый пост)
А напрямую удалять запись объекта через SQL-команды не корректно: может нарушиться ссылочная целостность. 

Все правильно - пусть этим занимается как минимум база данных. А хибернат пусть ей в этом помогает.
Аминь.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)