代码之家  ›  专栏  ›  技术社区  ›  Chris F

为什么对一个对象同时调用NHibernate OnPreInsert和OnPreUpdate方法

  •  1
  • Chris F  · 技术社区  · 16 年前

    我在PreSaveEventListener中使用NHibernate OnPreInsert和OnPreUpdate事件来设置实体的CreatedDate和ModifiedDate。问题是,有两个实体 二者都 事件在我第一次创建时被触发。 因为在OnPreInsert事件之后不会保存实体状态,所以OnPreUpdate事件在一个全新的实体状态上运行,并且我的CreatedDate永远不会被设置

    起初,我认为这是因为我的代码在事务结束前发起了两个SaveOrUpdate背对背调用。果然,我找到了一些这样的代码。但后来我意识到这仍然发生在另一个实体身上。据我所知,只有这两个实体有这个问题。我通过在它们的构造函数中设置CreatedDate临时解决了这个问题,但我想避免这种情况。

    这是我的结构:
    业务实体(具有两个具体连接子类的抽象类)

    编辑: 我最近意识到它也发生在另一个对象(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 回复  |  直到 16 年前
        1
  •  0
  •   mefcorvi    16 年前

    事件侦听器在我的项目中引发了许多不同的问题,其中许多问题对我来说没有意义。我认为,如果NHibernate在创建实体后真的更新了实体,可能会导致您的问题。NHibernate可以更新实体的版本或为其设置一些id(或guid)。你能把发布实体的映射放在这里吗?我还建议您在profiler中查看sql查询。

        2
  •  0
  •   Dave Clemmer manu    13 年前

    实际上我遇到了这个问题,可能是同一个问题。

    StringTrimEnd 执行此操作的typehandler在插入数据库之前或在检索字符串之后修剪字符串的结尾。

    嗯,我实施了 Equals 方法返回的值为false Equals(object x, object y) 当x和y为空时。

    因此,当我创建一个带有空字符串的新对象时,它将加载的值(null)与当前值(null)进行比较,并决定需要更新(以及插入)。

    也许这会在某个时候帮助某人。

        3
  •  0
  •   Vladimir    13 年前