代码之家  ›  专栏  ›  技术社区  ›  Kendrick

IPreInsertEventListener未为子对象触发

  •  0
  • Kendrick  · 技术社区  · 15 年前

    我已经接通了 IPreInsertEventListener IPreUpdateEventListener 在我的应用程序中管理审计日志,该应用程序使用NHibernate作为ORM层。

    我的问题是 OnPreInsert() 事件在对象被持久化时激发,但对于每个插入的子对象也不会激发。

    Canine ,其中包含 CanineHandlers . 正在发生的是:

    1. 新建 犬科动物
    2. CanineHandler 并将其添加到我新创建的 犬科动物
    3. 犬科动物
    4. OnPreInsert 用新创建的 犬科动物 还有我的 LastUpdated LastUpdatedBy 字段已填充。
    5. not-null property references a null or transient value Model.CanineHandler.LastUpdatedBy

    显然问题是 上次更新 在NHibernate验证 犬类装卸工 重新插入

    我玩过的一个选择是将另一个属性添加到 Auditable 包含一组 子对象,但严格地说,我可以保存 犬类装卸工 犬科动物 父项已更改,然后我将以相反的方向级联插入/更新。

    所以,我是在正确的轨道上与一些不正确的代码某处,还是我应该采取不同的方式来处理这个问题。

    下面是相关的(截断的)代码:

    可审计接口

    public interface IAuditable
    {
        DateTime LastUpdated { get; set; }
        int? LastUpdatedBy { get; set; }
        string AuditTypeName { get; }
        Object AuditGetNew(String changes);
    }
    

    OnPreInsert事件处理程序(实现IPreInsertEventListener接口)

    public bool OnPreInsert(PreInsertEvent insertEvent)
    {
        if (insertEvent.Entity is IAuditable)
        {
            IAuditable auditablePoco = insertEvent.Entity as IAuditable;
            auditablePoco.LastUpdated = DateTime.Now;
            auditablePoco.LastUpdatedBy = (int?)PersonID;
            //Taken directly from Ayende's blog, these calls update the
            //event's state to match the entity's state
            Set(insertEvent.Persister, insertEvent.State, "LastUpdated", auditablePoco.LastUpdated);
            Set(insertEvent.Persister, insertEvent.State, "LastUpdatedBy", auditablePoco.LastUpdatedBy);
        }
        return false;
    }
    

    犬标测

    <hibernate-mapping namespace="CanineApp.Model" assembly="CanineApp.Model" xmlns="urn:nhibernate-mapping-2.2">
      <class name="Canine" table="Canine">
        <id name="CanineID" type="Int32">
          <generator class="identity" />
        </id>
        <property name="Name" type="String" length="64" not-null="true" />
        <property name="LastUpdated" type="Date" />
        <property name="LastUpdatedBy" type="Int32" />
        <set name="CanineHandlers" table="CanineHandler" inverse="true" 
            order-by="EffectiveDate desc" cascade="save-update"
            access="field.camelcase-underscore">
          <key column="CanineID" />
          <one-to-many class="CanineHandler" />
        </set>
        </class>
    </hibernate-mapping>
    

    <hibernate-mapping namespace="OPS.CanineApp.Model" assembly="OPS.CanineApp.Model" xmlns="urn:nhibernate-mapping-2.2">
      <class name="CanineHandler" table="CanineHandler" schema="dbo">
        <id name="CanineHandlerID" type="Int32">
          <generator class="identity" />
        </id>
        <property name="HandlerPersonID" type="Int64" precision="19" not-null="true" />
        <property name="EffectiveDate" type="DateTime" precision="16" not-null="true" />
        <property name="LastUpdated" type="Date" not-null="true" />
        <property name="LastUpdatedBy" type="Int32" not-null="true" />
        <many-to-one name="Canine" class="Canine" column="CanineID" not-null="true" access="field.camelcase-underscore" />
      </class>
    </hibernate-mapping>
    
    1 回复  |  直到 15 年前
        1
  •  1
  •   Iain    15 年前

    不确定这是否有效,但我注意到,LastUpdatedBy和LastUpdated的Canine映射与CanineHandler的不同。或许可以尝试从CanineHandler映射中删除not null=“true”。

    我以同样的方式对nHibernate进行了审计,虽然我使用了旧的截取接口,即IInterceptor,但它工作得很好。此外,我的映射中没有null=“true”。

    <hibernate-mapping namespace="OPS.CanineApp.Model" assembly="OPS.CanineApp.Model" xmlns="urn:nhibernate-mapping-2.2">
      <class name="CanineHandler" table="CanineHandler" schema="dbo">
        <id name="CanineHandlerID" type="Int32">
          <generator class="identity" />
        </id>
        <property name="HandlerPersonID" type="Int64" precision="19" not-null="true" />
        <property name="EffectiveDate" type="DateTime" precision="16" not-null="true" />
        <property name="LastUpdated" type="Date"  />
        <property name="LastUpdatedBy" type="Int32"  />
        <many-to-one name="Canine" class="Canine" column="CanineID" not-null="true" access="field.camelcase-underscore" />
      </class>
    </hibernate-mapping>