IPreInsertEventListener不保存到数据库

IPreInsertEventListener不保存到数据库

本文介绍了NHibernate的IPreUpdateEventListener,IPreInsertEventListener不保存到数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现我的实体简单的审计。审计实体实施 ITimestampable 接口,它定义了 DateAdded DateModified 属性。

I'm trying to implement simple auditing on my entities. Auditable entities implement the ITimestampable interface which defines DateAdded and DateModified properties.

我创建并注册一个事件侦听器来填充这些值。这里是完整的代码

I created and registered a event listener to populate these values. Here is the complete code.

internal class TimeStampEventListener : IPreUpdateEventListener, IPreInsertEventListener
    {
        public bool OnPreUpdate(PreUpdateEvent e)
        {
            if (e.Entity is ITimestampable)
            {
                (e.Entity as ITimestampable).DateModified = DateTime.Now;
            }

            return false;
        }

        public bool OnPreInsert(PreInsertEvent e)
        {
            if (e.Entity is ITimestampable)
            {
                (e.Entity as ITimestampable).DateAdded = DateTime.Now;
            }

            return false;
        }

        public void Register(Configuration configuration)
        {
            configuration.SetListener(ListenerType.PreInsert, this);
            configuration.SetListener(ListenerType.PreUpdate, this);
        }
    }

现在,当我提出一个会话红晕,监听器被调用,审计属性都设置正确,但大多数时候他们不会保存到数据库。通过大部分时间我的意思是很少的价值真正得到坚持。我不知道,但它看起来像上的应用程序启动后的第一个插入/更新,这更加怪异。

Now, when I make a session flush, the listener gets called, audit properties are correctly set, but most of the time they are not saved to the DB. By "most of the time" I mean that very rarely the values actually get persisted. I'm not sure, but it looks like on the first insert/update after the app is started, which is even more weird.

当然,首先我做一个更改为实体的变化仍然存在,但审计属性不是。

Of course, first I make a change to the entity, the change is persisted, but the audit property is not.

当我看到在事件探查器生成的SQL我看到NULL是寄于查询,而不是当前的时间,所以我猜它不是一个DB的问题。顺便说一句。我使用MySQL和 DateAdded DateModified 列是日期键入

When I look at the generated SQL in the profiler I see that NULL is send in the query instead of the current time, so I'm guessing it is not a DB issues. Btw. I'm using MySQL and DateAdded and DateModified column are DATE type.

在NHibernate的网站,这些属性映射仅作为<性> 。也许我错过了一些特殊的映射,这样的情况下...?

On the NHibernate site these properties are mapped only as <property>. Maybe I'm missing some "special" mapping for cases like these... ?

我完全停留在此。任何形式的帮助表示赞赏。

I'm completely stuck on this. Any kind of help is appreciated.

推荐答案

答案将被隐藏/这表明从Ayende的文章引用

The answer would be hidden/revealed in this cites from Ayende's article



  • NHibernate IPreUpdateEventListener & IPreInsertEventListener

...这里说到的精妙,但是。我们不能只更新实体状态。这其中的原因很简单,是从实体状态实体和地方,任何更改,我们对实体状态将不会反映在实体本身中提取的实体状态。可能导致数据库行和走出去同步,并引起一大堆真的讨厌的问题,你不知道从哪里开始调试实体实例。

您必须更新两个在这两个事件侦听器实体和实体状态(这个不一定在其他听众的情况下,顺便说一句)。下面是使用这些事件侦听器的一个简单的例子:

You have to update both the entity and the entity state in these two event listeners (this is not necessarily the case in other listeners, by the way). Here is a simple example of using these event listeners:

这是显示的代码如何,从同一篇文章:

This is the code showing how to, from the same article:

public class AuditEventListener : IPreUpdateEventListener, IPreInsertEventListener
{
    public bool OnPreUpdate(PreUpdateEvent @event)
    {
        var audit = @event.Entity as IHaveAuditInformation;
        if (audit == null)
            return false;

        var time = DateTime.Now;
        var name = WindowsIdentity.GetCurrent().Name;

        Set(@event.Persister, @event.State, "UpdatedAt", time);
        Set(@event.Persister, @event.State, "UpdatedBy", name);

        audit.UpdatedAt = time;
        audit.UpdatedBy = name;

        return false;
    }

    public bool OnPreInsert(PreInsertEvent @event)
    {
        var audit = @event.Entity as IHaveAuditInformation;
        if (audit == null)
            return false;


        var time = DateTime.Now;
        var name = WindowsIdentity.GetCurrent().Name;

        Set(@event.Persister, @event.State, "CreatedAt", time);
        Set(@event.Persister, @event.State, "UpdatedAt", time);
        Set(@event.Persister, @event.State, "CreatedBy", name);
        Set(@event.Persister, @event.State, "UpdatedBy", name);

        audit.CreatedAt = time;
        audit.CreatedBy = name;
        audit.UpdatedAt = time;
        audit.UpdatedBy = name;

        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;
}

这篇关于NHibernate的IPreUpdateEventListener,IPreInsertEventListener不保存到数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 07:33
查看更多