Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint" / 25 сообщений из 32, страница 1 из 2
27.06.2010, 15:58
    #36710245
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Всем доброго времени суток. Пишу тестовый пример, который был бы способен удалять данные с помощью NHibernate.

Классы:
Код: plaintext
1.
2.
3.
4.
public class Book
{
    public virtual string Name { get; set; }
    public virtual Color Color { get; set; }
}

Код: plaintext
1.
2.
3.
4.
public class Color
{
    public virtual string Name { get; set; }
    public virtual IList<Book> Books { get; set; }
}

Маппинги:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHPoligon" assembly="NHPoligon" default-lazy="false">

  <class name="Book" table="books" >
    <id column="Id" type="int">
      <generator class="native"/>
    </id>

    <property name="Name" type="string" column="name"/>

    <many-to-one name="Color" class="Color" cascade="all-delete-orphan"  >
      <column name="idColor"/>
    </many-to-one>

  </class>
  
</hibernate-mapping>

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHPoligon" assembly="NHPoligon" default-lazy="false">

  <class name="Color" table="colors">

    <id column="Id" type="int">
      <generator class="native"/>
    </id>

    <property name="Name" type="string" column="name"/>

    <bag name="Books" inverse="true">
      <key column="Id"/>
      <one-to-many class="Book"/>  
    </bag>
    
  </class>

</hibernate-mapping>


В базе данных завел две книги, ссылающихся на один цвет (FirstBook и SecondBook ссылаются на цвет Orange)

Теперь, в отдельной сессии, делаю так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
using (NHibernate.ISession session = SessionManager.OpenSession())
{
    Book book = (Book)session.CreateCriteria(typeof(Book)).Add(Expression.Eq("Name", "First book")).UniqueResult();
    
    session.Delete(book);

    session.Flush();
}

При этом появляется исключение:

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.
NHibernate: DELETE FROM books WHERE Id = @p0;@p0 = 26
NHibernate: DELETE FROM colors WHERE Id = @p0;@p0 = 10

в то время, когда на удаляемый color есть ссылка из другого объекта Book, который в этой сессии не подгружен => NHibernate о нем не знает.

Вопрос: Можно-ли заставить NHibernate автоматически проверять, существуют ли ссылки на цвета из других книг, чтобы не удалять такие цвета при удалении книги?

P.S. Такая же ситуация (с тем же самым exception) случалась и с "многие-ко-многним".

Заранее спасибо.
Заранее спасибо.
...
Рейтинг: 0 / 0
27.06.2010, 19:26
    #36710353
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Pregamil,

он перед удаление залазит в базу за удаляемыми книгами по цвету, причем тут другая сессия.
то есть он берет самые свежие данные повсем книгам выбранного цвета.. подгружена не подгружена, это он сам решает что делать.
зы или я опять что не понял..
...
Рейтинг: 0 / 0
27.06.2010, 20:37
    #36710379
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Тогда немного разъясню.

Как писал выше, в базе данных имеется две книжки, ссылающиеся на один цвет.

Сначала выполняется запрос для выбора одной из двух имеющихся в базе книг:

Код: plaintext
Book book = (Book)session.CreateCriteria(typeof(Book)).Add(Expression.Eq("Name", "First book")).UniqueResult();

При этом на базу идут запросы:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SELECT this_.Id as Id0_1_, 
       this_.name as name0_1_, 
       this_.idColor as idColor0_1_, 
       color2_.Id as Id1_0_, 
       color2_.name as name1_0_ 
FROM books this_ 
left outer join colors color2_ on this_.idColor=color2_.Id 
WHERE this_.name = @p0;@p0 = 'First book'


SELECT books0_.Id as Id2_, 
       books0_.Id as Id0_1_, 
       books0_.name as name0_1_, 
       books0_.idColor as idColor0_1_, 
       color1_.Id as Id1_0_, 
       color1_.name as name1_0_ 
FROM books books0_ 
left outer join colors color1_ on books0_.idColor=color1_.Id 
WHERE books0_.Id=@p0;@p0 =  10 

Потом я пытаюсь удалить эту книжку:

Код: plaintext
1.
session.Delete(book);
session.Flush();

При этом на базу идут запросы:

Код: plaintext
1.
DELETE FROM books WHERE Id = @p0;@p0 =  30 
DELETE FROM colors WHERE Id = @p0;@p0 =  10 

И тут же программа вылетает с исключением:

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 не проверил, есть ли еще книги, ссылающиеся на удаляемый цвет, и попытался удалить эту книжку вместе с цветом. А это нарушает целостность данных. Вопрос в том, есть ли способ заставить эту ОРМ делать проверки перед удалением?
...
Рейтинг: 0 / 0
27.06.2010, 22:03
    #36710427
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Pregamil,

вот второй запрос и есть все книги, которые имеют этот цвет.
сделайте вот что.
уберите из мапа default-lazy="false" отовсюду, отсутствие ленивости и джойны всю картину смазывают.
да насилие над базой.
закомментируйте делите и и флеш, уберите отладку, и сделайте прогон.
на базу пойдет один запрос селект, на выбор вашей книги.
ну типа select * from book where name=`First book`
потом раскоментируйте строки и сделайте прогон с удалением.
к первоначальному селекту
добавится селект на выбор колора.
select * from color where id=10
потом хибер должен вытащить все книги
с этим цветом
(вдруг ваша другая сессия что добавила.)
select * from book where colorID=10;
а потом удалять.сначало книжки а потом солор
вот так должно быть согласно вашему мапу.
может вы этого хотели?
...
Рейтинг: 0 / 0
28.06.2010, 00:01
    #36710530
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Убрал default-lazy

Маппинги:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHPoligon" assembly="NHPoligon">

  <class name="Color" table="colors">

    <id column="Id" type="int">
      <generator class="native"/>
    </id>

    <property name="Name" type="string" column="name"/>

    <bag name="Books" inverse="true">
      <key column="Id"/>
      <one-to-many class="Book"/>  
    </bag>
    
  </class>

</hibernate-mapping>

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHPoligon" assembly="NHPoligon">

  <class name="Book" table="books" >
    <id column="Id" type="int">
      <generator class="native"/>
    </id>

    <property name="Name" type="string" column="name"/>

    <many-to-one name="Color" class="Color" cascade="all-delete-orphan"  >
      <column name="idColor"/>
    </many-to-one>

  </class>
  
</hibernate-mapping>

Шаг1

Код: plaintext
1.
Book book = (Book)session.CreateCriteria(typeof(Book)).Add(Expression.Eq("Name", "First book")).UniqueResult();

Код: plaintext
1.
2.
3.
4.
SELECT this_.Id as Id0_0_, 
           this_.name as name0_0_, 
           this_.idColor as idColor0_0_ 
FROM books this_ 
WHERE this_.name = @p0;@p0 = 'First book'

Шаг 2

Код: plaintext
session.Delete(book);

Код: plaintext
1.
2.
3.
SELECT color0_.Id as Id1_0_, 
           color0_.name as name1_0_ 
FROM colors color0_ 
WHERE color0_.Id=@p0;@p0 =  10 

Шаг 3

Код: plaintext
session.Flush();

Код: plaintext
1.
DELETE FROM books WHERE Id = @p0;@p0 =  32 
DELETE FROM colors WHERE Id = @p0;@p0 =  10 

Код: plaintext
1.
2.
3.
4.
5.
NHibernate.Exceptions.GenericADOException was unhandled
  Message="could not delete: [NHPoligon.Color#10][SQL: DELETE FROM colors WHERE Id = ?]"
  Source="NHibernate"
  SqlString="DELETE FROM colors WHERE Id = ?"
Message="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 снова пытается удалить Color, на который всё еще есть ссылающиеся книжки...

Мне нужно, чтобы ORM проверяла, если есть еще другие ссылающиеся на цвет книжки, то не трогала цвет. Если ссылающихся на цвет книжек больше нет, то удаляла этот цвет.
...
Рейтинг: 0 / 0
28.06.2010, 00:06
    #36710533
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Где-то в степипотом хибер должен вытащить все книги с этим цветом (вдруг ваша другая сессия что добавила.)
select * from book where colorID=10;
По сути, этого и не хватает... А в идеале хотелось бы TSQL-проверки IF EXISTS , но сомневаюсь, что с NHibernate такое является возможным. Уже хотябы первым способом, но чтобы работало...
...
Рейтинг: 0 / 0
28.06.2010, 10:46
    #36710847
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Насколько я знаю, NHibernate не будет рекурсивно искать зависимости между объектами. (В случае многие ко многим представляете во что это выльется? Truncate table быстрее и проще.)
Моё мнение - у вас ошибка в проектировании. Определитесь с объектом, который будет отвечать за время жизни своих составляющих. Гради Буч неплохо раскрывал эту тему в книге по ОО анализу и проектированию.
...
Рейтинг: 0 / 0
28.06.2010, 11:25
    #36710929
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
SolYUtorМоё мнение - у вас ошибка в проектировании. Определитесь с объектом, который будет отвечать за время жизни своих составляющих. Гради Буч неплохо раскрывал эту тему в книге по ОО анализу и проектированию.
На счет ошибки в проектировании - у меня ассоциация типа aggregation, не composition, то есть время жизни цвета совсем не равно времени жизни книжки. А ОРМ, думаю, должна уметь распознать такие вещи и не допускать REFERENCE-constraint конфликтов.
...
Рейтинг: 0 / 0
28.06.2010, 11:30
    #36710940
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Если время жизни цвета не равно времени жизни книжки - то цвет не должен удалятся при удалении книжки. Каскадное удаление там лишнее.
...
Рейтинг: 0 / 0
28.06.2010, 11:39
    #36710971
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
SolYUtorЕсли время жизни цвета не равно времени жизни книжки - то цвет не должен удалятся при удалении книжки. Каскадное удаление там лишнее.
Хорошо. Как тогда удалять цвета, на которые больше не осталось ссылок с книжек? На сколько я понимаю, этим занимается all-delete-orhpan? Или его нужно ставить на сторону цвета, а не книжки?
...
Рейтинг: 0 / 0
28.06.2010, 11:45
    #36710987
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
В цвета и книжки нужно удалять отдельно. Для цветов, по которым книжек не осталось, можно HQL применить.
...
Рейтинг: 0 / 0
28.06.2010, 12:03
    #36711033
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Стало быть, если каскадом можно удалять только под-объекты с меньшим либо равным временем жизни, чем у агрегирующего их объекта, то зачем придумали all-delete-orphan? Ведь в этом случае одиночек быть не может, все "вложенные" объекты и так будут удаляться. А если время жизни разное, то, по этой логике, каскад применять нельзя...

И еще, как же тогда с этим?
Где-то в степи потом хибер должен вытащить все книги с этим цветом (вдруг ваша другая сессия что добавила.)
select * from book where colorID=10;
...
Рейтинг: 0 / 0
28.06.2010, 12:25
    #36711078
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Ответ на ваш вопрос есть в документации, пункт 9.9 и 19 .

Насчёт топика Где-то в степи, я у меня есть сомнения, что он отражает реальное поведение NHibernate. Да, если выключить lazy - то граф объектов хибер действительно загрузит полностью. Но это не значит, что при удалении одного объекта он будет удалять остальные.
...
Рейтинг: 0 / 0
28.06.2010, 12:38
    #36711104
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Большое спасибо, очень помогли!

Ключевые идеи:
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().
...
Рейтинг: 0 / 0
28.06.2010, 12:46
    #36711119
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Я бы еще заострил внимание на отличии 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.
...
Рейтинг: 0 / 0
28.06.2010, 13:14
    #36711184
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
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?
...
Рейтинг: 0 / 0
28.06.2010, 13:35
    #36711221
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Мне тоже кажется, что слово 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" - будет удалён.

Специально проверять сейчас лениво. :)
...
Рейтинг: 0 / 0
28.06.2010, 13:59
    #36711264
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
А я проверил :)

Код: plaintext
<many-to-one name="Color" class="Color" cascade="all-delete-orphan">

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
using (NHibernate.ISession session = SessionManager.OpenSession())
{
    Book book = (Book)session.CreateCriteria(typeof(Book)).Add(Expression.Eq("Name", "First book")).UniqueResult();

    //Меняю цвет на новый, а старый остается без владельца
    book.Color = new Color() { Name = "Фиолетовый" };
    book.Color.Books.Add(book);

    session.Save(book);
    session.Flush();
}

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

Также попробовал убрать из класса Color коллекцию книг, чтобы со стороны цвета не было ссылок на книги. А в маппинге книги cascade="all-delete-orphan" оставил. Попробовал прогнать еще раз - эффект тот же, одиночки не были удалены.

(вот пример второго варианта)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHPoligon" assembly="NHPoligon">

  <class name="Color" table="colors">

    <id column="Id" type="int">
      <generator class="native"/>
    </id>

    <property name="Name" type="string" column="name"/>

  </class>

</hibernate-mapping>

Код: plaintext
1.
2.
3.
public class Color
{
    public virtual string Name { get; set; }
}

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
using (NHibernate.ISession session = SessionManager.OpenSession())
{
    Book book = (Book)session.CreateCriteria(typeof(Book)).Add(Expression.Eq("Name", "First book")).UniqueResult();

    book.Color = new Color(){Name = "Фиолетовый-3"};

    session.Save(book);
    session.Flush();
}

Поэтому cascade="all-delete-orphan" для меня пока что остается загадкой...
...
Рейтинг: 0 / 0
28.06.2010, 14:25
    #36711328
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Посмотрите, какие запросы формирует NHibernate при таком коде. (При этом предполагается, что Color - child, Book - parent.)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
using (NHibernate.ISession session = SessionManager.OpenSession())
{
    Book book = (Book)session.CreateCriteria(typeof(Book)).Add(Expression.Eq("Name", "First book")).UniqueResult();

    book.Color = new Color(){Name = "Фиолетовый-3"};

    session.Save(book);
    session.Flush();
    session.Clear();

    book2Compare = session.Get<Book>(book.Id);
    book2Compare.Color = null;

    session.SaveOrUpdate(book2Compare);
    session.Flush();
}
...
Рейтинг: 0 / 0
28.06.2010, 14:58
    #36711393
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Шаг 1

Код: plaintext
Book book = (Book)session.CreateCriteria(typeof(Book)).Add(Expression.Eq("Name", "First book")).UniqueResult();

Код: plaintext
1.
2.
3.
SELECT this_.Id as Id0_0_, this_.name as name0_0_, this_.idColor as idColor0_0_ 
FROM books this_ 
WHERE this_.name = @p0;@p0 = 'First book'


Шаг 2

Код: plaintext
1.
2.
book.Color = new Colorr() { Name = "Фиолетовый-5" };
session.Save(book);
session.Flush();

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
INSERT INTO colors (name) 
VALUES (@p0); 

select SCOPE_IDENTITY();@p0= 'Фиолетовый-5'

UPDATE books 
SET name = @p0, idColor = @p1 
WHERE Id = @p2;@p0 = 'First book', @p1 =  14 , @p2 =  33 

Шаг 3

Код: plaintext
1.
2.
session.Clear();

Book book2Compare = session.Get<Book>(book.Id);

Код: plaintext
1.
2.
SELECT book0_.Id as Id0_0_, book0_.name as name0_0_, book0_.idColor as idColor0_0_ 
FROM books book0_ 
WHERE book0_.Id=@p0;@p0 =  33 

Шаг 4

Код: plaintext
1.
2.
3.
4.
book2Compare.Color = null;

session.SaveOrUpdate(book2Compare);
session.Flush();

Код: plaintext
UPDATE books SET name = @p0, idColor = @p1 WHERE Id = @p2;@p0 = 'First book', @p1 = NULL, @p2 =  33 
...
Рейтинг: 0 / 0
28.06.2010, 16:03
    #36711575
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
После изучения документации и нескольких опытов установлено следующее: 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.
    public class Book
    {
        private IList<Color> _colors;
        private string _name;
        private int _id;

        public Book()
        {
            _colors = new List<Color>();
        }
        public virtual string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public virtual IList<Color> Colors
        {
            get { return _colors; }
            set { _colors = value; }
        }

        public virtual int Id
        {
            get { return _id; }
            set { _id = value; }
        }
    }

    public class Color
    {
        private int _id;
        private string _name;

        public virtual string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public virtual int Id
        {
            get { return _id; }
            set { _id = value; }
        }
    }

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHibernate.Probing" assembly="NHibernate.Probing">

	<class name="Book" table="books">
		<id name="Id" column="Id">
			<generator class="native" />
		</id>
		<property name="Name" type="string" column="name" />
		<bag name="Colors" cascade="all">
			<key column="BookId"/>
			<one-to-many class="Color"/>
		</bag>
	</class>

	<class name="Color" table="colors">
		<id column="Id" name="Id">
			<generator class="native" />
		</id>
		<property name="Name" type="string" column="name" />
	</class>

</hibernate-mapping>

Код: 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.
 [TestFixture]
    public class NHibernateFixture
    {
        #region Setup/Teardown

        [SetUp]
        public void SetUp()
        {
            _config = new Configuration();
            _config.Configure("hibernate.cfg.xml");

            _sessionFactory = _config.BuildSessionFactory();
            new SchemaExport(_config).Drop(false, true);
            new SchemaExport(_config).Execute(false, true, false);
        }

        #endregion

        private ISessionFactory _sessionFactory;
        private Configuration _config;

        [Test]
        public void Test()
        {
            using (ISession session = _sessionFactory.OpenSession())
            {
                Book book = new Book();

                book.Colors.Add(new Color());

                session.SaveOrUpdate(book);
                session.Flush();
                session.Clear();

                Book book2Compare = session.Get<Book>(book.Id);
                book2Compare.Colors.Clear();

                session.SaveOrUpdate(book2Compare);
                session.Flush();
            }
        }
    }

...
Рейтинг: 0 / 0
28.06.2010, 16:40
    #36711683
Pregamil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Супер! Спасибо большое, буду знать :)
...
Рейтинг: 0 / 0
28.06.2010, 17:52
    #36711836
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
SolYUtor,

Дело принципа, сделал приложение по данному мапу, мап идентичный таблици тоже
вот поведение хибера.
1 вытаскивание книги
Код: plaintext
SELECT this_.Id as Id0_0_, this_.Name as Name0_0_, this_.idColor as idColor0_0_ FROM Book1 this_ WHERE  this_.Name = @p0; @p0 = 'First book'

2 удаление книг.

Код: plaintext
1.
//вытаскиваем цвет книги.
SELECT color0_.Id as Id1_0_, color0_.Name as Name1_0_ FROM Color color0_ WHERE color0_.Id=@p0; @p0 = '12'

втаскиваем все книги этого цвета
Код: plaintext
SELECT book0_.IdColor as IdColor__1_, book0_.Id as Id1_, book0_.Id as Id0_0_, book0_.Name as Name0_0_, book0_.idColor as idColor0_0_ FROM Book1 book0_ WHERE book0_.IdColor=@p0; @p0 = '12'
делаем все книги что не смогли вытащить мусором
Код: plaintext
UPDATE Book1 SET IdColor = null WHERE IdColor = @p0; @p0 = '12'

удаляем книги ( 2 книги ссылаются на один цвет)
и цвет
Код: plaintext
1.
2.
2010-06-28 17:39:46,343 [11] DEBUG NHibernate.SQL - DELETE FROM Book1 WHERE Id = @p0; @p0 = '5'
2010-06-28 17:39:46,343 [11] DEBUG NHibernate.SQL - DELETE FROM Book1 WHERE Id = @p0; @p0 = '6'
2010-06-28 17:39:46,359 [11] DEBUG NHibernate.SQL - DELETE FROM Color WHERE Id = @p0; @p0 = '12'
стоит отметить, насчет мусора, это при ленивой загрузке
при не ленивой, если книга добавлена в другой сессии жибер уже не тянет все книги одного цвета, он просто отправляет добавленные в мусор


......................хибер 1.2
Код: plaintext
1.
2.
3.
<property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

запросы взяты из лога хибера.
...
Рейтинг: 0 / 0
28.06.2010, 18:17
    #36711865
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
Где-то в степи,

приложите код на C#, как и что делаете.
...
Рейтинг: 0 / 0
28.06.2010, 18:24
    #36711871
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint"
SolYUtor,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
private void button1_Click(object sender, EventArgs e)
        {
            ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
            ISession session = sessionFactory.OpenSession();
            Book book = (Book)session.CreateCriteria(typeof(Book)).Add(Expression.Eq("Name", "First book")).UniqueResult();
            session.Delete(book);
            session.Flush();
        }
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate cascade delete - "DELETE statement conflicted with the REFERENCE constraint" / 25 сообщений из 32, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]