<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Finite Epiphany &#187; nhibernate</title>
	<atom:link href="http://finite.mikeandcorinne.com/category/nhibernate/feed/" rel="self" type="application/rss+xml" />
	<link>http://finite.mikeandcorinne.com</link>
	<description>Mike&#039;s thoughts on programming and tech</description>
	<lastBuildDate>Mon, 08 Nov 2010 06:44:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>Intercepting nHibernate events in ActiveRecord (or how to automatically set Update and Create dates)</title>
		<link>http://finite.mikeandcorinne.com/2007/07/intercepting-nhibernate-events-in-activerecord-or-how-to-automatically-set-update-and-create-dates/</link>
		<comments>http://finite.mikeandcorinne.com/2007/07/intercepting-nhibernate-events-in-activerecord-or-how-to-automatically-set-update-and-create-dates/#comments</comments>
		<pubDate>Thu, 26 Jul 2007 05:29:19 +0000</pubDate>
		<dc:creator>Mike Thomas</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[nhibernate]]></category>

		<guid isPermaLink="false">http://www.mikeandcorinne.com/code/?p=4</guid>
		<description><![CDATA[I am currently working on a large .NET web application that I am just now porting to use nHibernate and ActiveRecord. I used MyGeneration to create entity classes based on the existing database schema and am using a pattern similar to Oren&#8217;s Repository&#60;T&#62; pattern. One implication of this is that all of my entity classes [...]]]></description>
			<content:encoded><![CDATA[<p>I am currently working on a large .NET web application that I am just now porting to use <a href="http://www.hibernate.org/343.html">nHibernate </a>and <a href="http://castleproject.org/activerecord/">ActiveRecord.</a>  I used <a href="http://sourceforge.net/projects/mygeneration">MyGeneration </a>to create entity classes based on the existing database schema and am using a pattern similar to <a href="http://www.ayende.com/Blog/Default.aspx">Oren&#8217;s</a> <a href="http://www.ayende.com/Blog/archive/2007/06/08/Rhino-Commons-RepositoryltTgt-and-Unit-Of-Work.aspx">Repository&lt;T&gt; </a>pattern.  One implication of this is that all of my entity classes do not derive from ActiveRecordBase&lt;T&gt;.  Instead, they all merely derive from my own EntityBase class.  When I started my project, the EntityBase class was empty &#8211; existing only as a &#8220;just in case&#8221; class.</p>
<p>Eventually, I ran across a problem.  Many but not all of my entities had CreateDate, CreateUser, RevisionDate, and RevisionUser properties.  Others just had a CreateDate and CreateUser but no RevisionDate or RevisionUser.  The most elementary way to handle something like this would be to do something like:</p>
<pre lang="csharp">
Person person = new Person();
person.CreateDate = DateTime.Now;
person.CreateUser = UserIdentity.Name;
Repository&lt;person&gt;.Save(person);
</pre>
<p>The problem with this approach is that you would have to maunally update the CreateDate and RevisionDate whenever you created or saved  an entity.  Not good.   Option two is to set the CreateDate and CreateUser in the constructor of all entities but that doesn&#8217;t solve the problem of the RevisionDate and RevisionUser.  In addition you are repeating that code in every entity class.</p>
<p>At this point, I stepped back and asked myself what the <strong>best</strong> way to do this would be, regardless of the framework:</p>
<ul>
<li>Whenever an object is INSERTed into the database and it has a CreateDate and CreateUser they should be set.</li>
<li>Whenever an object has been changed and is being UPDATEd to the database and it has a RevisionDate and Revision user they should be set.</li>
</ul>
<p>Having that in mind, I created two interfaces:</p>
<pre lang="csharp">
interface IHasCreateStamp {
     DateTime CreateDate{get; set;}
     DateTime CreateUser{get; set;}
}

interface IHasRevisionStamp{/*omited*/}
</pre>
<p>Having applied these interfaces to the appropriate classes I now had to find where I could intercept the nHibernate Save and FlushDirty events.  It took me more time that I would like to find this, but in the end the solution (while not ideal) is quite simple.  ActiveRecords sets a nHibernate IInterceptor that forwards all nHibernate events to the appropriate ActiveRecord entity classes as long as they inherit from ActiveRecordHooksBase.  I had to modify my EntityBase class to inherit from ActiveRecordHooksBase and in my EntityBase class am able to override the OnFlushDirty method:</p>
<pre lang="csharp">
protected override bool OnFlushDirty(object id, IDictionary previousState, IDictionary currentState, IType[] types) {
     if(this is IHasRevisionStamp) {
          DateTime now = DateTime.Now;
          string userPcid = SecurityHelper.GetCurrentIdentity().PeopleCodeId;

          currentState["RevisionDate"] = now;
          currentState["RevisionOpid"] = userPcid;

          return true;
     }
     return false;
}
</pre>
<p>In the OnFlushDirty  you are able to modify the currentState and any changes you make will be propagated to the database.  You also have to make sure to return &#8220;true&#8221; if you make any modifications.</p>
<p>Once that and the BeforeSave methods were overridden all CreateDates and RevisionDates are set automatically.  One great benefit too, is that a RevisionDate will only be updated if the entity has changed.</p>
]]></content:encoded>
			<wfw:commentRss>http://finite.mikeandcorinne.com/2007/07/intercepting-nhibernate-events-in-activerecord-or-how-to-automatically-set-update-and-create-dates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

