|
|
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Всем доброго времени суток. Пишу тестовый пример, который был бы способен удалять данные с помощью NHibernate. Классы: Код: plaintext 1. 2. 3. 4. Код: plaintext 1. 2. 3. 4. Маппинги: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. В базе данных завел две книги, ссылающихся на один цвет (FirstBook и SecondBook ссылаются на цвет Orange) Теперь, в отдельной сессии, делаю так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. При этом появляется исключение: The DELETE statement conflicted with the REFERENCE constraint \"FK_books_colors\". The conflict occurred in database \"NHPoligon\", table \"dbo.books\", column 'idColor'.\r\nThe statement has been terminated. То есть, NHibernate видит каскад, и пытается выполнить два оператора Delete на базе данных: Код: plaintext 1. в то время, когда на удаляемый color есть ссылка из другого объекта Book, который в этой сессии не подгружен => NHibernate о нем не знает. Вопрос: Можно-ли заставить NHibernate автоматически проверять, существуют ли ссылки на цвета из других книг, чтобы не удалять такие цвета при удалении книги? P.S. Такая же ситуация (с тем же самым exception) случалась и с "многие-ко-многним". Заранее спасибо. Заранее спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2010, 15:58 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Pregamil, он перед удаление залазит в базу за удаляемыми книгами по цвету, причем тут другая сессия. то есть он берет самые свежие данные повсем книгам выбранного цвета.. подгружена не подгружена, это он сам решает что делать. зы или я опять что не понял.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2010, 19:26 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Тогда немного разъясню. Как писал выше, в базе данных имеется две книжки, ссылающиеся на один цвет. Сначала выполняется запрос для выбора одной из двух имеющихся в базе книг: Код: plaintext При этом на базу идут запросы: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Потом я пытаюсь удалить эту книжку: Код: plaintext 1. При этом на базу идут запросы: Код: plaintext 1. И тут же программа вылетает с исключением: The DELETE statement conflicted with the REFERENCE constraint \"FK_books_colors\". The conflict occurred in database \"NHPoligon\", table \"dbo.books\", column 'idColor'.\r\nThe statement has been terminated. То есть NHibernate не проверил, есть ли еще книги, ссылающиеся на удаляемый цвет, и попытался удалить эту книжку вместе с цветом. А это нарушает целостность данных. Вопрос в том, есть ли способ заставить эту ОРМ делать проверки перед удалением? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2010, 20:37 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Pregamil, вот второй запрос и есть все книги, которые имеют этот цвет. сделайте вот что. уберите из мапа default-lazy="false" отовсюду, отсутствие ленивости и джойны всю картину смазывают. да насилие над базой. закомментируйте делите и и флеш, уберите отладку, и сделайте прогон. на базу пойдет один запрос селект, на выбор вашей книги. ну типа select * from book where name=`First book` потом раскоментируйте строки и сделайте прогон с удалением. к первоначальному селекту добавится селект на выбор колора. select * from color where id=10 потом хибер должен вытащить все книги с этим цветом (вдруг ваша другая сессия что добавила.) select * from book where colorID=10; а потом удалять.сначало книжки а потом солор вот так должно быть согласно вашему мапу. может вы этого хотели? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2010, 22:03 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Убрал default-lazy Маппинги: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Шаг1 Код: plaintext 1. Код: plaintext 1. 2. 3. 4. Шаг 2 Код: plaintext Код: plaintext 1. 2. 3. Шаг 3 Код: plaintext Код: plaintext 1. Код: plaintext 1. 2. 3. 4. 5. ================== Исключение снова появляется, так как NHibernate снова пытается удалить Color, на который всё еще есть ссылающиеся книжки... Мне нужно, чтобы ORM проверяла, если есть еще другие ссылающиеся на цвет книжки, то не трогала цвет. Если ссылающихся на цвет книжек больше нет, то удаляла этот цвет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 00:01 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Где-то в степипотом хибер должен вытащить все книги с этим цветом (вдруг ваша другая сессия что добавила.) select * from book where colorID=10; По сути, этого и не хватает... А в идеале хотелось бы TSQL-проверки IF EXISTS , но сомневаюсь, что с NHibernate такое является возможным. Уже хотябы первым способом, но чтобы работало... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 00:06 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Насколько я знаю, NHibernate не будет рекурсивно искать зависимости между объектами. (В случае многие ко многим представляете во что это выльется? Truncate table быстрее и проще.) Моё мнение - у вас ошибка в проектировании. Определитесь с объектом, который будет отвечать за время жизни своих составляющих. Гради Буч неплохо раскрывал эту тему в книге по ОО анализу и проектированию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 10:46 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
SolYUtorМоё мнение - у вас ошибка в проектировании. Определитесь с объектом, который будет отвечать за время жизни своих составляющих. Гради Буч неплохо раскрывал эту тему в книге по ОО анализу и проектированию. На счет ошибки в проектировании - у меня ассоциация типа aggregation, не composition, то есть время жизни цвета совсем не равно времени жизни книжки. А ОРМ, думаю, должна уметь распознать такие вещи и не допускать REFERENCE-constraint конфликтов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 11:25 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Если время жизни цвета не равно времени жизни книжки - то цвет не должен удалятся при удалении книжки. Каскадное удаление там лишнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 11:30 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
SolYUtorЕсли время жизни цвета не равно времени жизни книжки - то цвет не должен удалятся при удалении книжки. Каскадное удаление там лишнее. Хорошо. Как тогда удалять цвета, на которые больше не осталось ссылок с книжек? На сколько я понимаю, этим занимается all-delete-orhpan? Или его нужно ставить на сторону цвета, а не книжки? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 11:39 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
В цвета и книжки нужно удалять отдельно. Для цветов, по которым книжек не осталось, можно HQL применить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 11:45 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Стало быть, если каскадом можно удалять только под-объекты с меньшим либо равным временем жизни, чем у агрегирующего их объекта, то зачем придумали all-delete-orphan? Ведь в этом случае одиночек быть не может, все "вложенные" объекты и так будут удаляться. А если время жизни разное, то, по этой логике, каскад применять нельзя... И еще, как же тогда с этим? Где-то в степи потом хибер должен вытащить все книги с этим цветом (вдруг ваша другая сессия что добавила.) select * from book where colorID=10; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 12:03 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Ответ на ваш вопрос есть в документации, пункт 9.9 и 19 . Насчёт топика Где-то в степи, я у меня есть сомнения, что он отражает реальное поведение NHibernate. Да, если выключить lazy - то граф объектов хибер действительно загрузит полностью. Но это не значит, что при удалении одного объекта он будет удалять остальные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 12:25 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Большое спасибо, очень помогли! Ключевые идеи: NHibernate documentationLikewise, to delete all objects in a graph, either * Delete() each individual object OR * map associated objects using cascade="all", cascade="all-delete-orphan" or cascade="delete". Recommendation: * If the child object's lifespan is bounded by the lifespan of the of the parent object make it a lifecycle object by specifying cascade="all". * Otherwise, Save() and Delete() it explicitly from application code. If you really want to save yourself some extra typing, use cascade="save-update" and explicit Delete(). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 12:38 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Я бы еще заострил внимание на отличии cascade="all" и cascade="all-delete-orphan": NHibernate documentationIf a transient child is dereferenced by a persistent parent, nothing special happens (the application should explicitly delete the child if necessary) unless cascade="all-delete-orphan", in which case the "orphaned" child is deleted. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 12:46 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
NHibernate documentstionIf a transient child is dereferenced by a persistent parent, nothing special happens (the application should explicitly delete the child if necessary) unless cascade="all-delete-orphan", in which case the "orphaned" child is deleted. А здесь не понятно. Как я понял: если несохраненный ранее в базу child был удален из коллекции объекта parent, то при выставленном cascade="all-delete-orphan" NHibernate будет удалять из базы заведомо несохраненный child? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 13:14 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Мне тоже кажется, что слово transient там лишнее. Наверно описка вышла. Чуть выше есть более точное выражение: NHibernate documentationMapping an association (many-to-one, or collection) with cascade="all" marks the association as a parent/child style relationship where save/update/deletion of the parent results in save/update/deletion of the child(ren). Futhermore, a mere reference to a child from a persistent parent will result in save / update of the child. The metaphor is incomplete, however. A child which becomes unreferenced by its parent is not automatically deleted, except in the case of a <one-to-many> association mapped with cascade="all-delete-orphan". И далее в примере п. 19.3 про transient тоже ни слова. Поэтому будем считать, что если Parent более не ссылается на Child, то в случае cascade="all" Child не будет удалён из базы, а в случае cascade="all-delete-orphan" - будет удалён. Специально проверять сейчас лениво. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 13:35 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
А я проверил :) Код: plaintext Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. При этом прошлый цвет, завязанный на одну только книгу, не удалился, несмотря на то, что ссылающихся на этот цвет книг больше не осталось. Пробовал каскад вставить и на сторону Color, эффект тот же самый, одиночки не были удалены :) Также попробовал убрать из класса Color коллекцию книг, чтобы со стороны цвета не было ссылок на книги. А в маппинге книги cascade="all-delete-orphan" оставил. Попробовал прогнать еще раз - эффект тот же, одиночки не были удалены. (вот пример второго варианта) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Код: plaintext 1. 2. 3. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Поэтому cascade="all-delete-orphan" для меня пока что остается загадкой... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 13:59 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Посмотрите, какие запросы формирует NHibernate при таком коде. (При этом предполагается, что Color - child, Book - parent.) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 14:25 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Шаг 1 Код: plaintext Код: plaintext 1. 2. 3. Шаг 2 Код: plaintext 1. 2. Код: plaintext 1. 2. 3. 4. 5. 6. 7. Шаг 3 Код: plaintext 1. 2. Код: plaintext 1. 2. Шаг 4 Код: plaintext 1. 2. 3. 4. Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 14:58 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
После изучения документации и нескольких опытов установлено следующее: all-delete-orphan работает только для коллекций. Я об этому успел успешно забыть. Проверка ниже. При "all" NHibernate только обновит Color (BookId = null), а при "all-delete-orphan" еще и удалит Color. опыты Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 16:03 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Супер! Спасибо большое, буду знать :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 16:40 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
SolYUtor, Дело принципа, сделал приложение по данному мапу, мап идентичный таблици тоже вот поведение хибера. 1 вытаскивание книги Код: plaintext 2 удаление книг. Код: plaintext 1. втаскиваем все книги этого цвета Код: plaintext Код: plaintext удаляем книги ( 2 книги ссылаются на один цвет) и цвет Код: plaintext 1. 2. при не ленивой, если книга добавлена в другой сессии жибер уже не тянет все книги одного цвета, он просто отправляет добавленные в мусор ......................хибер 1.2 Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 17:52 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
Где-то в степи, приложите код на C#, как и что делаете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 18:17 |
|
||
|
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
|
|||
|---|---|---|---|
|
#18+
SolYUtor, Код: plaintext 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2010, 18:24 |
|
||
|
|

start [/forum/topic.php?fid=17&msg=36710971&tid=1351218]: |
0ms |
get settings: |
6ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
143ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
| others: | 210ms |
| total: | 444ms |

| 0 / 0 |
