Почему оба метода NHibernate OnPreInsert и OnPreUpdate вызываются для объекта - PullRequest
1 голос
/ 02 марта 2010

Я использую события NHibernate OnPreInsert и OnPreUpdate в PreSaveEventListener для установки CreatedDate и ModifiedDate моих сущностей. Проблема в том, что есть две сущности, для которых оба события запускаются при первом их создании. Это вызывает проблему , так как состояние объекта не сохраняется после события OnPreInsert, поэтому событие OnPreUpdate работает со всем новым состоянием объекта, и мой CreatedDate никогда не устанавливается (по умолчанию 01/01 / 0001).

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

Вот моя структура:
Бизнес-объект (абстрактный класс, который имеет два конкретных объединенных подкласса)
Организация BusinessContact, имеющая отношения «многие к одному» с Business

РЕДАКТИРОВАТЬ: Недавно я понял, что это также происходит на одном другом объекте (InvoiceLineItem), но не почти идентичный объект (BillLineItem), созданный и используется почти идентичными способами. Кажется довольно произвольным.

Кто-нибудь видел это раньше?

Вот код слушателя события:

public class PreSaveEventListener : IPreInsertEventListener, IPreUpdateEventListener {
    public bool OnPreInsert(PreInsertEvent @event) {
        EntityWithGuidId entity = @event.Entity as EntityWithGuidId;

        if (null != entity) {
            var createdDate = DateTime.Now;
            var modifiedDate= DateTime.Now;
            Set(@event.Persister, @event.State, "CreatedDate", createdDate);
            Set(@event.Persister, @event.State, "ModifiedDate", modifiedDate);
            entity.CreatedDate = createdDate;
            entity.ModifiedDate = modifiedDate;
        }

        return false;
    }

    public bool OnPreUpdate(PreUpdateEvent @event) {
        EntityWithGuidId entity = @event.Entity as EntityWithGuidId;

        if (null != entity) {
            var modifiedDate= DateTime.Now;
            Set(@event.Persister, @event.State, "ModifiedDate", modifiedDate);
            entity.ModifiedDate = modifiedDate;
        }

        return false;
    }

    private void Set(IEntityPersister persister, object[] state, string propertyName, object value) {
        var index = Array.IndexOf(persister.PropertyNames, propertyName);
        if (index == -1)
            return;
        state[index] = value;
    }
}

Ответы [ 3 ]

0 голосов
/ 20 апреля 2012

Я действительно столкнулся с этим, есть вероятность, что это может быть та же проблема.

Я реализовал свой собственный обработчик типов StringTrimEnd, который делал именно это, обрезал конец строк перед вставкой в ​​базу данных или после их извлечения.

Хорошо, я реализовал метод Equals неправильно, и он возвратил false для Equals(object x, object y), когда x и y, где ноль.

Поэтому, когда я создал новый объект с пустой строкой, он сравнил загруженное значение (null) с текущим значением (null) и решил, что необходимо обновление (а также вставка).

Может быть, это поможет кому-нибудь в какой-то момент.

0 голосов
/ 19 апреля 2013

В БД имеется поле, которое можно обнулять, которое не было отмечено как обнуляемое в NH

0 голосов
/ 04 мая 2010

Слушатели событий вызвали много разных проблем в моем проекте, и многие из них не имеют смысла для меня. Я думаю, что ваша проблема может быть вызвана тем, что NHibernate действительно обновляет вашу сущность после ее создания. NHibernate может обновить версию объекта или установить для него некоторый идентификатор (или guid). Можете ли вы поставить здесь отображение выданного лица? Я также предлагаю вам посмотреть на sql запросы в профилировщике.

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