Будет ли NHibernate попытаться сохранить один и тот же объект дважды в этом сценарии? - PullRequest
2 голосов
/ 25 февраля 2010

Допустим, у меня есть две сущности: Stable и Pony.

Stable имеет IList<Pony> с отображением HasMany, настроенным для Cascade.All().

Это означает, что если я сделаю session.Save(myStable), каждый Pony в коллекции будет сохранен.

Однако что произойдет, если я сделаю это?

Pony myLittlePony = new Pony(Color.Brown);
Stable myStable = new Stable(WoodTypes.RichMahogany);
myStable.Ponies.Add(myLittlePony);

session.Save(myStable);
session.Save(myLittlePony);

Будет ли NHibernate пытаться сохранить myLittlePony дважды ? или NHibernate достаточно «умен», чтобы знать, что myLittlePony уже сохранен в БД?

Есть ли какие-либо последствия для производительности от выполнения чего-то подобного?

Ответы [ 6 ]

2 голосов
/ 26 февраля 2010

Вероятно, он будет сохранен только один раз *, когда транзакция сбрасывается, но вам нужно пометить одну сторону отношения (обычно коллекцию) как обратную сторону, чтобы обозначить не владельца отношения. Это обеспечит согласованность поведения. Если вы не пометите коллекцию как обратную сторону отношения, NH выполнит вставку, затем обновите дочерний объект внешним ключом от родительского объекта. Это, очевидно, потерпит неудачу, если есть необнуляемое ограничение FK.

  • Я предполагаю, что внутренне NH сохранит объект дважды, но при втором сохранении не будет сгенерирована операция с базой данных, поскольку объект не будет иметь ожидающих изменений в этот момент.
2 голосов
/ 25 февраля 2010

NHibernate довольно умный, и AFAIK, поскольку myLittlePony по-прежнему будет в сеансе и не будет иметь изменений (IsDirty возвращает false), он не вызовет еще один сброс в постоянную среду.

0 голосов
/ 26 февраля 2010

Я считаю, что то, что вы делаете, на самом деле то, что вам нужно , чтобы сделать. Единственный способ работы с отдельным session.Save(myStable); - правильно настроить каскадные отношения для стабильного класса.

0 голосов
/ 25 февраля 2010

.Save () не делает ничего, кроме как сообщает сессии о вашем новом объекте *. NH работает только тогда, когда сеанс сбрасывается в базу данных, что обычно происходит при фиксации транзакции. Он никогда не напишет одну и ту же сущность дважды.

(* ОК, он может перейти в базу данных, если вы используете неверный генератор идентификаторов)

0 голосов
/ 25 февраля 2010

Если есть SQL Server, запустите SQL Profiler, чтобы увидеть, что происходит, но NHibernate должен сохранить этот объект только один.

0 голосов
/ 25 февраля 2010

Сохраняется только один раз.

И на самом деле ничто обычно не попадает в базу данных, пока вы не совершите транзакцию или не очистите сеанс.

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