我已经连接了IPreInsertEventListener
和IPreUpdateEventListener
来管理我的应用中的审核日志记录,它使用NHibernate作为ORM层。
我遇到的问题是,当持久化对象时会触发OnPreInsert()
事件,但也不会为每个插入的子对象触发事件。
在我的情况下,我有一个Canine
,其集合为CanineHandlers
。发生的事情是:
Canine
CanineHandler
并将其添加到我新创建的Canine
Canine
OnPreInsert
会因新创建的Canine
和我的LastUpdated
&填充了LastUpdatedBy
个字段。not-null property references a null or transient value Model.CanineHandler.LastUpdatedBy
显然问题是在NHibernate验证LastUpdated
实例之前没有填充CanineHandler
字段,但我无法弄清楚如何让NHibernate调用{{ 1}}用于持久保存到数据库的每个实例的方法。
我玩过的一个选项是在我的OnPreInsert
POCO中添加另一个属性,其中包含一组Auditable
个子对象,但从技术上讲,我可以保存一个Auditable
修改后的CanineHandler
父级已被更改,然后我将以相反的方向级联插入/更新。
那么,我是否在某个地方使用了一些不正确的代码,或者我应该以不同的方式接近它。
这是相关的(截断的)代码:
Canine
public interface IAuditable
{
DateTime LastUpdated { get; set; }
int? LastUpdatedBy { get; set; }
string AuditTypeName { get; }
Object AuditGetNew(String changes);
}
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>
答案 0 :(得分:1)
不确定这会有效,但我注意到LastUpdatedBy和LastUpdated的Canine映射与CanineHandler的不同。也许尝试从CanineHandler映射中删除not-null =“true”。
我已经以相同的方式对nHibernate进行了审计,虽然我使用了较旧的拦截界面,即IInterceptor,但它运行良好。我的映射中也没有not-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>