<?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>The Inquisitive Coder - Davy Brion&#039;s Blog &#187; NHibernate</title> <atom:link href="http://davybrion.com/blog/category/nhibernate/feed/" rel="self" type="application/rss+xml" /><link>http://davybrion.com/blog</link> <description>inquisitive: adjective. given to inquiry, research, or asking questions; eager for knowledge; intellectually curious</description> <lastBuildDate>Sun, 29 Jan 2012 10:48:12 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>(Ab)Using Conventions To Enforce Good Practices</title><link>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/</link> <comments>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/#comments</comments> <pubDate>Thu, 26 Jan 2012 19:15:29 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3886</guid> <description><![CDATA[I always tell people to explicitly specify the lengths of their string properties in their NHibernate mappings for performance reasons. If you don't specify them, the ADO.NET parameter lengths of those strings will always be set to the length of the actual string value that's been assigned to the parameter. This is a problem for [...]]]></description> <content:encoded><![CDATA[<p>I always tell people to explicitly specify the lengths of their string properties in their NHibernate mappings for performance reasons. If you don't specify them, the ADO.NET parameter lengths of those strings will always be set to the length of the actual string value that's been assigned to the parameter. This is a problem for SQL Server, because it can't cache those statements as efficiently as it would if the parameter lengths were always the same for a given statement. Simply put, if you don't specify the lengths, SQL Server's statement cache gets polluted with a bunch of statements that are often the same, but they're considered to be different simply because of the lengths of those string parameters. And this can really hurt the performance of your application.</p><p>Of course, not everyone remembers to set those lengths, so I thought it'd be great if I could force people to do this. With a little creative use of Fluent NHibernate's conventions, it's quite easy to enforce this:</p><div><pre class="brush: csharp; title: ; notranslate">
public class StringsMustHaveLengthConvention: IPropertyConvention, IPropertyConventionAcceptance
{
    public void Apply(IPropertyInstance instance)
    {
        var msg = string.Format(&quot;The string property '{0}' of type '{1}' does not have a length value specified, &quot; +
            &quot;which is required for performance reasons. Add something like this to your mapping override:\r\n&quot; + 
            &quot;\tmapping.Map(e =&gt; e.{0}).Length(50); // with an appropriate length for this property&quot;,
            instance.Property.Name, instance.EntityType.Name);

        throw new MappingException(msg);
    }

    public void Accept(IAcceptanceCriteria&lt;IPropertyInspector&gt; criteria)
    {
        criteria.Expect(x =&gt; x.Type == typeof(string)).Expect(x =&gt; x.Length == 0);
    }
}
</pre></div><p>With that convention in place, you won't even be able to run your code until you've specified the string lengths <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2012%2F01%2Fabusing-conventions-to-enforce-good-practices%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/"  data-text="(Ab)Using Conventions To Enforce Good Practices" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/feed/</wfw:commentRss> <slash:comments>15</slash:comments> </item> <item><title>Review Of My NHibernate Course</title><link>http://davybrion.com/blog/2011/07/review-of-my-nhibernate-course/</link> <comments>http://davybrion.com/blog/2011/07/review-of-my-nhibernate-course/#comments</comments> <pubDate>Wed, 06 Jul 2011 17:22:05 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3351</guid> <description><![CDATA[Sorry for the shameful promotion, but you would do it too . Bart Deleye was kind enough to write a review of my NHibernate course which i'd like to share here: Davy's NHibernate course is an excellent cocktail based on ingredients like expertise, high quality content, hands-on labs and best practices. Day 1 starts with [...]]]></description> <content:encoded><![CDATA[<p>Sorry for the shameful promotion, but you would do it too <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . <a
href="http://twitter.com/#!/bartdeleye" target="_blank">Bart Deleye</a> was kind enough to write a review of my <a
href="http://thatextramile.be/training/nhibernate">NHibernate course</a> which i'd like to share here:</p><div><blockquote><p>Davy's NHibernate course is an excellent cocktail based on ingredients like expertise, high quality content, hands-on labs and best practices.</p><p>Day 1 starts with an introduction on ORM's in general after which we take a deep dive in the different configuration options (both using HBM files and Fluent NHibernate) from which you’ll acquire a thorough understanding of the mapping capabilities and the different solutions NHibernate provides for the impedance mismatch. Afterwards the theory will be applied in practice during the hands-on labs that are test-driven by NUnit code samples. This style of exercises not only clearly illustrates the usage of NHibernate but also provides you a nice toolkit to experiment further after the course. We finished the day with best practices on transaction/session management in different environments (web applications, services and desktop applications).</p><p>During Day 2 you will grasp the fundamental details of all query methods available in NHibernate with their pro's and con's. The course is based on NH 3 by the way, so you will learn everything on HQL, Criteria, QueryOver and LINQ. During the hands-on labs you will implement some nice challenging queries. Afterwards you will learn a lot of best and worst practices regarding performance with optimizations like Futures (query batching), statement batching, executable HQL, fetching strategies, projecting, and leaning on the session cache. The second day is finished with a session on the different concurrency strategies.</p><p>Day 3 covers a lot of advanced techniques that make your NHibernate skill set complete like Identifier and Inheritance strategies, Advanced Mappings, Second Level Cache, Stateless Sessions, … To finish the course, you’ll have to fix some red tests during the exercises.</p><p>I can only recommend this course to every new, novice and experienced NHibernate user. Only a few weeks later I notice a lot of improvement amongst my team members!<p></blockquote></div><p>Bart and his team were the first people to attend the course almost 2 months ago, so i wasn't entirely sure yet of the format and the content at that time. This week i'm actually doing the course for the third time, and apart from some very minor changes and tweaks, it's pretty much the exact same as when i did it the first time, except that i'm not nearly as nervous now as i was when i did it the first time. Luckily for me, his team was fun to hang out with and there was plenty of joking around which definitely made it easy to just be comfortable instead of being a nervous wreck <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F07%2Freview-of-my-nhibernate-course%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/07/review-of-my-nhibernate-course/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/07/review-of-my-nhibernate-course/"  data-text="Review Of My NHibernate Course" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/07/review-of-my-nhibernate-course/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/07/review-of-my-nhibernate-course/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/07/review-of-my-nhibernate-course/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Recent Additions To My NHibernate Examples</title><link>http://davybrion.com/blog/2011/05/recent-additions-to-my-nhibernate-examples/</link> <comments>http://davybrion.com/blog/2011/05/recent-additions-to-my-nhibernate-examples/#comments</comments> <pubDate>Sun, 08 May 2011 19:55:05 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3273</guid> <description><![CDATA[I've been pretty busy lately with the prep-work for my NHibernate course and my NHibernate examples, which the course leans on pretty heavily. Below is a list of examples that have been added in the past few weeks: optimistic concurrency optimistic-lock="all" optimistic-lock="dirty" version pessimistic locking performance executable hql (updates/deletes) extra lazy collection futures paging through [...]]]></description> <content:encoded><![CDATA[<p>I've been pretty busy lately with the prep-work for my NHibernate course and my NHibernate examples, which the course leans on pretty heavily.  Below is a list of examples that have been added in the past few weeks:</p><ul><li>optimistic concurrency<ul><li>optimistic-lock="all"</li><li>optimistic-lock="dirty"</li><li>version</li></ul></li><li>pessimistic locking</li><li>performance<ul><li>executable hql (updates/deletes)</li><li>extra lazy collection</li><li>futures</li><li>paging through collections</li><li>proxies</li></ul></li><li>querying<ul><li>aggregate functions (HQL/Criteria/LINQ/QueryOver)</li><li>eager fetching (HQL/Criteria/LINQ/QueryOver)</li><li>group by (HQL/Criteria/LINQ/QueryOver)</li><li>ordering (HQL/Criteria/LINQ/QueryOver)</li><li>paging (HQL/Criteria/LINQ/QueryOver)</li><li>polymorphism (HQL/Criteria/LINQ/QueryOver)</li><li>projections (HQL/Criteria/LINQ/QueryOver)</li><li>restrictions (HQL/Criteria/LINQ/QueryOver)</li><li>subqueries (HQL/Criteria/LINQ/QueryOver)</li><li>unique results (HQL/Criteria/LINQ/QueryOver)</li><li>native sql</li><li>stored procedures</li></ul></li></ul><p>And there's quite a bit more to come in the next 2 weeks or so...</p><p>The examples now also run on SQL Server with both Fluent NHibernate as well as normal mapping files. If you're interested, you can get them <a
href="https://github.com/davybrion/NHibernateWorkshop">here</a>.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F05%2Frecent-additions-to-my-nhibernate-examples%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/05/recent-additions-to-my-nhibernate-examples/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/05/recent-additions-to-my-nhibernate-examples/"  data-text="Recent Additions To My NHibernate Examples" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/05/recent-additions-to-my-nhibernate-examples/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/05/recent-additions-to-my-nhibernate-examples/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/05/recent-additions-to-my-nhibernate-examples/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>NHibernate Examples</title><link>http://davybrion.com/blog/2011/04/nhibernate-examples/</link> <comments>http://davybrion.com/blog/2011/04/nhibernate-examples/#comments</comments> <pubDate>Sun, 10 Apr 2011 15:36:55 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3263</guid> <description><![CDATA[I published some NHibernate examples almost 4 years ago, and they still get downloaded pretty frequently. Unfortunately they still use NHibernate 1.2 and are somewhat limited as to what they demonstrate. My NHibernate course is rather example/exercise-heavy so i thought it would be a good time to replace those outdated examples with new ones and [...]]]></description> <content:encoded><![CDATA[<p>I published some NHibernate examples almost 4 years ago, and they still get downloaded pretty frequently.  Unfortunately they still use NHibernate 1.2 and are somewhat limited as to what they demonstrate. <a
href="http://thatextramile.be/training/nhibernate">My NHibernate course</a> is rather example/exercise-heavy so i thought it would be a good time to replace those outdated examples with new ones and make them available to anyone who wants them.  The examples are not complete yet, but will be updated frequently in the next couple of weeks.  After that, i intend to keep them up to date to demonstrate new NHibernate features as they are introduced with new releases.  Of course, you're more than welcome to contribute examples of your own.</p><p>The solution consists of a suite of automated tests that run on a SQLite database, which demonstrate some features of NHibernate. All tests currently run with the classic HBM mapping files and FluentNHibernate. Choosing which of the two is used can be done by selecting the correct build configuration (either HBMSQLITE or FLUENTSQLITE) before running the tests.  Running the tests doesn't require any software to be installed or any configuration to be performed by you. Though you can obviously run the tests on different databases if you want to.  The object model that is used is based on Northwind with a couple of changes.  The object model can evolve into whatever it needs to be to showcase NHibernate features/usage.  Some other models might also be introduced later on to show features that wouldn't fit well with the Northwind-based model.</p><p>These examples could be useful to people who are new to NHibernate, but could be interesting for experienced NHibernate users as well, if only as a playground to quickly experiment with some features that you're unsure of.</p><p>You can find the code <a
href="https://github.com/davybrion/NHibernateWorkshop">here</a> or you can always download the latest version <a
href="https://github.com/davybrion/NHibernateWorkshop/archives/master">here</a>.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F04%2Fnhibernate-examples%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/04/nhibernate-examples/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/04/nhibernate-examples/"  data-text="NHibernate Examples" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/04/nhibernate-examples/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/04/nhibernate-examples/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/04/nhibernate-examples/feed/</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>NHibernate Course: Cancelled</title><link>http://davybrion.com/blog/2011/03/nhibernate-course-cancelled/</link> <comments>http://davybrion.com/blog/2011/03/nhibernate-course-cancelled/#comments</comments> <pubDate>Mon, 21 Mar 2011 21:44:11 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3197</guid> <description><![CDATA[I'm sorry to say that the NHibernate course i was going to give in April has been cancelled because there were too few registrations to make it worthwhile. Some people have inquired about the possibility of doing the course privately on-site, so the effort i've put into the prep-work might not be a total waste [...]]]></description> <content:encoded><![CDATA[<p>I'm sorry to say that the NHibernate course i was going to give in April has been cancelled because there were too few registrations to make it worthwhile. Some people have inquired about the possibility of doing the course privately on-site, so the effort i've put into the prep-work might not be a total waste <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .  I plan on making the examples i've prepared available for free on Github, so hopefully they'll be of good help to people who are new to NHibernate or for those who quickly want to experiment with some specific NHibernate features. I'll probably release it sometime next week since i intend to enjoy a bit of the spare time i've been missing lately <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .  They're not complete yet and more examples will be added over time by myself, and perhaps some contributions from people who want to add to them.</p><p>To those who did register: thanks for wanting to come, and sorry that you won't be able to.  Perhaps some other time.</p><p><strong>Update: First customer for having the course on-site has signed up. If you're interested in that as well, get in touch.</strong> <strong>Update 2: new date for the public course is <a
href="http://www.sparkles.be/training/nhibernatemasterclass2011.aspx">June 20-22</a></strong></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F03%2Fnhibernate-course-cancelled%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/03/nhibernate-course-cancelled/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/03/nhibernate-course-cancelled/"  data-text="NHibernate Course: Cancelled" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/03/nhibernate-course-cancelled/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/03/nhibernate-course-cancelled/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/03/nhibernate-course-cancelled/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Reminder: My NHibernate Course Is Coming Up</title><link>http://davybrion.com/blog/2011/03/reminder-my-nhibernate-course-is-coming-up/</link> <comments>http://davybrion.com/blog/2011/03/reminder-my-nhibernate-course-is-coming-up/#comments</comments> <pubDate>Tue, 08 Mar 2011 22:11:25 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3174</guid> <description><![CDATA[Just a reminder: my NHibernate course will be held from April 4th to the 6th in Belgium, and you can still register. You'll not only learn a lot about what NHibernate can do, you'll learn how to use it wisely. The format of the course will be pretty hands-on, meaning that there are plenty of [...]]]></description> <content:encoded><![CDATA[<p>Just a reminder: my <a
href="http://www.sparkles.be/training/nhibernatemasterclass2011.aspx">NHibernate course</a> will be held from April 4th to the 6th in Belgium, and you can still register.  You'll not only learn a lot about what NHibernate can do, you'll learn how to use it <em>wisely</em>. The format of the course will be pretty hands-on, meaning that there are plenty of exercises for you to complete.  Theory and exercises will be mixed constantly throughout the day, at a rather rapid pace so you won't get a chance to get bored.  In fact, i challenge you to get bored during the course! <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /></p><p>This is the agenda for the course:</p><p>Day 1:</p><ul><li>Quick ORM Introduction</li><li>Configuration</li><li>Classes &#038; Mapping (hbm &#038; fluent-nhibernate)<ul><li>Entities</li><li>One-to-many associations</li><li>Many-to-one associations</li><li>Inheritance</li></ul></li><li>Session/Transaction Management<ul><li>In web applications</li><li>In service layers</li></ul></li><li>Transitive Persistence<ul><li>Transient &#038; Persistent Entities</li><li>Cascades</li><li>Detached Entities</li></ul></li></ul><p>Day 2:</p><ul><li>Querying<ul><li>HQL</li><li>Criteria</li><li>QueryOver</li><li>LINQ</li><li>Polymorphic Queries</li><li>Named Queries</li></ul></li><li>Performance Optimizations<ul><li>Paging</li><li>Projections</li><li>Future Queries</li><li>Batching DML statements</li><li>Executable HQL (deletes/updates)</li><li>Stored Procedures/Views</li><li>Using native SQL</li></ul></li><li>Optimistic Concurrency strategies</li><li>Pessimistic Locking</li></ul><p>Day 3:</p><ul><li>Identifier strategies</li><li>Inheritance strategies</li><li>Advanced mappings<ul><li>Value type collections</li><li>Components</li><li>Component collections</li><li>(composite) User Types</li><li>Many-to-Many associations</li><li>Polymorphic associations</li></ul></li><li>2nd Level cache<ul><li>Caching entities</li><li>Caching collections</li><li>Caching queries</li></ul></li><li>Stateless Sessions</li></ul><p>(Sorry for this shameless plug, but you'd do it too if you were me <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F03%2Freminder-my-nhibernate-course-is-coming-up%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/03/reminder-my-nhibernate-course-is-coming-up/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/03/reminder-my-nhibernate-course-is-coming-up/"  data-text="Reminder: My NHibernate Course Is Coming Up" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/03/reminder-my-nhibernate-course-is-coming-up/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/03/reminder-my-nhibernate-course-is-coming-up/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/03/reminder-my-nhibernate-course-is-coming-up/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Full Details Of My NHibernate Course Are Available</title><link>http://davybrion.com/blog/2011/01/full-details-of-my-nhibernate-course-are-available/</link> <comments>http://davybrion.com/blog/2011/01/full-details-of-my-nhibernate-course-are-available/#comments</comments> <pubDate>Tue, 04 Jan 2011 11:14:25 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2983</guid> <description><![CDATA[I've teamed up with Sparkles to organize an NHibernate course. It'll be an intensive 3-day course, from April 4th to the 6th. The location still needs to be decided but it will be in Belgium. Full details are available here. All attendees will also receive a copy of the NHibernate 3.0 Cookbook. Hope to see [...]]]></description> <content:encoded><![CDATA[<p>I've teamed up with <a
href="http://www.sparkles.be">Sparkles</a> to organize an NHibernate course. It'll be an intensive 3-day course, from April 4th to the 6th. The location still needs to be decided but it will be in Belgium.  Full details are available <a
href="http://www.sparkles.be/training/nhibernatemasterclass2011.aspx">here</a>.  All attendees will also receive a copy of the <a
href="https://www.packtpub.com/nhibernate-3-0-cookbook/book">NHibernate 3.0 Cookbook</a>.  Hope to see some of you there <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F01%2Ffull-details-of-my-nhibernate-course-are-available%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/01/full-details-of-my-nhibernate-course-are-available/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/01/full-details-of-my-nhibernate-course-are-available/"  data-text="Full Details Of My NHibernate Course Are Available" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/01/full-details-of-my-nhibernate-course-are-available/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/01/full-details-of-my-nhibernate-course-are-available/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/01/full-details-of-my-nhibernate-course-are-available/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>What Should I Cover In My NHibernate Workshop?</title><link>http://davybrion.com/blog/2010/12/what-should-i-cover-in-my-nhibernate-workshop/</link> <comments>http://davybrion.com/blog/2010/12/what-should-i-cover-in-my-nhibernate-workshop/#comments</comments> <pubDate>Wed, 29 Dec 2010 16:38:01 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2972</guid> <description><![CDATA[I'm gonna do an NHibernate training/workshop in a few months, and before i can start preparing for it, i need to know what i'm going to cover in the workshop. The workshop should be 3 or maybe 4 days and the goal is that everyone attending it will learn a ton about what you can [...]]]></description> <content:encoded><![CDATA[<p>I'm gonna do an NHibernate training/workshop in a few months, and before i can start preparing for it, i need to know what i'm going to cover in the workshop.  The workshop should be 3 or maybe 4 days and the goal is that everyone attending it will learn a ton about what you can do with NHibernate, as well as how you <em>should</em> use it.</p><p>I just made a list of stuff that i'd like to cover, which is already pretty long.  I'd rather start off with a long list and if necessary make some cuts if it turns out to be too much.  If you guys have any tips on what else i should include, please let me know <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Here's the current list:</p><ul><li>Configuration</li><li>Classes &#038; Mapping (hbm and FluentNHibernate)<ul><li>entities</li><li>one-to-many associations (unidirectional &#038; bidirectional)</li><li>many-to-one associations (unidirectional &#038; bidirectional)</li><li>inheritance</li></ul></li><li>Session/Transaction Management<ul><li>session/transaction management in a web app</li><li>session/transaction management in a service layer</li></ul></li><li>Transitive Persistence<ul><li>transient and persistent entities</li><li>cascades</li><li>detached entities</li></ul></li><li>Querying<ul><li>HQL</li><li>criteria</li><li>QueryOver</li><li>LINQ</li><li>polymorphic queries</li><li>named queries</li></ul></li><li>Performance optimisations<ul><li>paging</li><li>projections</li><li>future queries</li><li>batching DML statements</li><li>executable HQL</li><li>retrieving data from stored procedures / views</li><li>using native SQL</li></ul></li><li>optimistic concurrency</li><li>pessimistic locking</li><li>identifier strategies</li><li>inheritance strategies</li><li>advanced mappings<ul><li>value types collections</li><li>components</li><li>component collections</li><li>(composite) user types</li><li>many-to-many associations (unidirectional &#038; bidirectional)</li><li>polymorphic associations (one-to-many, many-to-one)</li></ul></li><li>2nd Level Cache<ul><li>entities</li><li>collections</li><li>queries</li></ul></li><li>stateless sessions (bulk data processing)</li><li>extending nhibernate<ul><li>custom implementations of NHibernate components</li><li>event listeners</li></ul></li></ul><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F12%2Fwhat-should-i-cover-in-my-nhibernate-workshop%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/12/what-should-i-cover-in-my-nhibernate-workshop/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/12/what-should-i-cover-in-my-nhibernate-workshop/"  data-text="What Should I Cover In My NHibernate Workshop?" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/12/what-should-i-cover-in-my-nhibernate-workshop/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/12/what-should-i-cover-in-my-nhibernate-workshop/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/12/what-should-i-cover-in-my-nhibernate-workshop/feed/</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>Recommended Book: NHibernate 3.0 Cookbook</title><link>http://davybrion.com/blog/2010/10/recommended-book-nhibernate-3-0-cookbook/</link> <comments>http://davybrion.com/blog/2010/10/recommended-book-nhibernate-3-0-cookbook/#comments</comments> <pubDate>Sun, 24 Oct 2010 21:07:05 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Books]]></category> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2840</guid> <description><![CDATA[The people from Packt Publishing asked me to review one of their new books, the NHibernate 3.0 Cookbook. I was a little hesitant at first to do yet another book review (don't worry, i'm gonna cut back on the reviews) but the NHibernate community needs a good, up to date NHibernate book and i was [...]]]></description> <content:encoded><![CDATA[<p>The people from <a
href="http://www.packtpub.com/">Packt Publishing</a> asked me to review one of their new books, the <a
href="https://www.packtpub.com/nhibernate-3-0-cookbook/book">NHibernate 3.0 Cookbook</a>.  I was a little hesitant at first to do yet another book review (don't worry, i'm gonna cut back on the reviews) but the NHibernate community needs a good, up to date NHibernate book and i was curious to see if this one could fill that void.</p><p>As the title says, it's a cookbook.  It consists of a bunch of recipes for a very large variety of NHibernate-related tasks.  These kind of books are usually pretty low on theory, but this one does a good job of backing up most of the recipes' practical steps with just enough of the background theory that you do need to use NHibernate effectively.  I still prefer the approach used in <a
href="http://www.amazon.com/NHibernate-Action-Pierre-Henri-Kuat%C3%A9/dp/1932394923/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1287952549&#038;sr=8-1">NHibernate In Action</a>, which is more heavy on theory, but that book unfortunately targets NHibernate 1.2.  This one covers a lot of the new things that have been introduced in NHibernate 2, 2.1 and the upcoming 3.0 version and as such, is the most suitable NHibernate book available right now.</p><p>I'm not gonna go over each chapter like i usually do, so if you want to get a a glimpse of what the book covers, just click <a
href="https://www.packtpub.com/toc/nhibernate-30-cookbook-table-contents">here</a>.  And as you can see, it covers quite a lot.  As usual with NHibernate books, i'd like to see a bit more pages being spent on querying, but this task only becomes harder as NHibernate keeps adding more querying API's.  Yes, both QueryOver and the LINQ Provider are covered.  Unfortunately, the whole chapter that deals with querying covers HQL, Criteria, QueryOver and LINQ in a mere 44 pages.  And while there are some examples of each, none of them are really covered in depth.  That's probably not the goal of this book, and it would indeed be hard for any book to cover all of those querying API's in depth while not boring the hell out of your readers, but it is something that a lot of readers are going to need to look into a bit more if they're going to use NHibernate in real applications.</p><p>But don't let my nitpicking on the querying chapter fool you.  This book is <em>very</em> useful to people who are new to NHibernate, and a lot of people who already have experience with it will learn a few new useful tricks or learn some things they didn't know yet.  And while it contains a lot of useful information, it also manages to be a pretty quick read.  And if you need any more convincing, just take a look at the price of the electronic version of this book <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F10%2Frecommended-book-nhibernate-3-0-cookbook%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/10/recommended-book-nhibernate-3-0-cookbook/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/10/recommended-book-nhibernate-3-0-cookbook/"  data-text="Recommended Book: NHibernate 3.0 Cookbook" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/10/recommended-book-nhibernate-3-0-cookbook/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/10/recommended-book-nhibernate-3-0-cookbook/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/10/recommended-book-nhibernate-3-0-cookbook/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Performance Of NHibernate With Ruby Objects Compared To Traditional C# Objects</title><link>http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/</link> <comments>http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/#comments</comments> <pubDate>Tue, 19 Oct 2010 14:22:38 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[IronRuby]]></category> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[Ruby]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2817</guid> <description><![CDATA[I recently showed how you can use NHibernate to persist and query Ruby objects through IronRuby. We've continued the experiment (though we've already done some big optimizations in the code based on the first results of these tests) and we recently had to decide whether or not the performance difference between using NHibernate with regular [...]]]></description> <content:encoded><![CDATA[<p>I recently showed how you can <a
href="http://davybrion.com/blog/2010/09/using-nhibernate-to-persist-and-query-ruby-objects/">use NHibernate to persist and query Ruby objects</a> through IronRuby. We've continued the experiment (though we've already done some big optimizations in the code based on the first results of these tests) and we recently had to decide whether or not the performance difference between using NHibernate with regular static C# code and using it with dynamic Ruby objects was acceptable.  So we ran a set of tests, and compared all of the numbers.  Note that we don't claim that these benchmarks are scientifically correct in any way, but we do think they give us a good idea on what we can reasonably expect.  I want to share the results with you, and would appreciate any feedback you guys have on this... particularly on whether or not we missed something obvious in our tests or whether or not we should trust these numbers. After all, we're not professional benchmarkers so our approach might very well just suck <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>We have a scenario which consists of 15 'actions'.  For these actions, we use some tables from the Chinook database, basically just Artist/Album/Track/Genre/MediaType.  The actions are the following:</p><ol><li>Retrieve single track without joins, and access each non-reference property</li><li>Retrieve single track with joins, and access all properties, including references</li><li>Retrieve single track without joins, and access all properties, including references (triggers lazy-loading)</li><li>Create and persist object graph: one artist with two albums with 13 tracks each</li><li>Retrieve created artist from nr 4, add a new album with another 13 tracks, change the title of the first album from nr 4, and remove the second album from nr 4 including its tracks</li><li>Retrieve created artist from nr 4 and delete its entire graph</li><li>Create a single track</li><li>Retrieve single track from step 7 and update it</li><li>Retrieve single track from step 7 and update the name of one of its referenced properties</li><li>Retrieve single track from step 7 and change one of the reference properties so it references a different instance</li><li>Delete the track from step 7</li><li>Retrieve 100 tracks and access each non-reference property</li><li>Retrieve 200 tracks and access each non-reference property</li><li>Retrieve 100 tracks without joins and access all properties, including references (triggers lazy-loading)</li><li>Retrieve 100 tracks with joins and access all properties, including references</li></ol><p>Note: when i say we access reference properties to trigger lazy loading, i mean that we access a non-id property of the referenced property to make sure it indeed hits the database.</p><p>The scenario is ran 500 times with regular C# objects, and 500 times with Ruby objects.  We keep track of the average time of each action in the scenario, as well as the total duration of the scenario.  Also, keep in mind that we ran these tests on a local database.</p><p>The following graph shows the average duration of each action in milliseconds on the Y axis, and the number of the action on the X axis:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_duration_of_each_action_in_millis.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_duration_of_each_action_in_millis.png" alt="" title="average_duration_of_each_action_in_millis" width="600" height="406" class="aligncenter size-medium wp-image-2818" /></a></p><p>(you can click on the graph to watch it in its full size)</p><p>Before i'll discuss these results, i'd also like to show the following graph which shows the average difference in milliseconds between the static and the dynamic execution of each action:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_difference_in_millis_for_each_action.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_difference_in_millis_for_each_action.png" alt="" title="average_difference_in_millis_for_each_action" width="600" height="418" class="aligncenter size-medium wp-image-2821" /></a></p><p>Two actions immediately stand out: the last two which both deal with fetching a set of items and accessing all of their properties.  They're both about 6ms slower than their static counterparts, which is a performance penalty of 71% for action 14, and 87% for action 15.  That deals with a part of code that we can't really optimize any more.  Well, it probably is possible but we've already done a lot of work on that, and this is the best we can come up with so far.</p><p>Now, those 2 actions are things we avoid as much as possible in real code anyway, so maybe they aren't that big of an issue.  The other 2 actions where there is a noticable difference (though it actually means an increase in average execution time of 1.1ms using a local database) is the creation and persistance of an object graph (step 4), and the retrieval/modification/persistence of that same graph (step 5).  Most other actions don't have a noticeable difference, and in some cases the dynamic version is actually faster than the static one, no doubt because NHibernate has in some cases less work to do when using the Map EntityMode (which we rely on for the dynamic stuff) compared to the Poco EntityMode.</p><p>We also wanted to see whether the performance difference would get worse when spreading the workload evenly over a set of threads, or even a 'pool' of IronRuby engines.  I was pretty happy to see that it didn't really lead to a noticeable difference.</p><p>The following graph shows the average duration of the entire scenario in a couple of different situations:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration.png" alt="" title="average_scenario_duration" width="462" height="363" class="aligncenter size-full wp-image-2822" /></a></p><p>I do have to mention that the numbers shown in this graph aren't averages, but the result from running the scenario once in each situation.  We did however ran the scenarios in each situation more than once, and while we didn't list the averages, the numbers are representative of each testrun... we didn't see any really noticeable differences over multiple runs.  The percentage difference for each situation is shown in this graph:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_difference.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_difference.png" alt="" title="average_scenario_duration_difference" width="395" height="365" class="aligncenter size-full wp-image-2825" /></a></p><p>As you can see, the performance penalty of the entire scenario in each situation varies between 15% and 26%.</p><p>Now, considering the fact that we prefer to avoid loading 'large' sets of data through NHibernate into entities (we prefer to use projections instead for that) we wanted to see what the difference would be for the entire duration of the scenario in each situation, without the final 4 actions.  Basically, just the typical CRUD scenarios:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_without_last_4_actions.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_without_last_4_actions.png" alt="" title="average_scenario_duration_without_last_4_actions" width="468" height="365" class="aligncenter size-full wp-image-2826" /></a></p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_difference_without_last_4_actions.png" rel="prettyPhoto[2817]"><img
src="http://davybrion.com/blog/wp-content/uploads/2010/10/average_scenario_duration_difference_without_last_4_actions.png" alt="" title="average_scenario_duration_difference_without_last_4_actions" width="405" height="368" class="aligncenter size-full wp-image-2827" /></a></p><p>Now the difference varies between 6% and 15%.</p><p>Now, suppose that we have a compelling reason to actually go ahead with using this approach (we do actually, but i'm not gonna get into that here), do you think we can trust these numbers? Is there anything else we're missing? Are we complete idiots for testing the performance difference like this?  Do you have any feedback whatsoever? Then please leave a comment <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F10%2Fperformance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/"  data-text="Performance Of NHibernate With Ruby Objects Compared To Traditional C# Objects" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/10/performance-of-nhibernate-with-ruby-objects-compared-to-traditional-c-objects/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Using NHibernate To Persist And Query Ruby Objects</title><link>http://davybrion.com/blog/2010/09/using-nhibernate-to-persist-and-query-ruby-objects/</link> <comments>http://davybrion.com/blog/2010/09/using-nhibernate-to-persist-and-query-ruby-objects/#comments</comments> <pubDate>Thu, 23 Sep 2010 21:16:35 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Ruby]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2687</guid> <description><![CDATA[As some of you already know, i've been experimenting with getting NHibernate and Ruby (through IronRuby) to play nice together. In this post, i'll go over what already works and how i got it working. Suppose we have the following 2 NHibernate mappings: And suppose we have the following 2 classes: The only atypical thing [...]]]></description> <content:encoded><![CDATA[<p>As some of you already know, i've been experimenting with getting NHibernate and Ruby (through IronRuby) to play nice together.  In this post, i'll go over what already works and how i got it working.</p><p>Suppose we have the following 2 NHibernate mappings:</p><div><pre class="brush: xml; title: ; notranslate">
  &lt;class entity-name=&quot;Artist&quot;&gt;
    &lt;id name=&quot;id&quot; column=&quot;ArtistId&quot; type=&quot;int&quot;&gt;
      &lt;generator class=&quot;identity&quot;/&gt;
    &lt;/id&gt;

    &lt;property name=&quot;name&quot; length=&quot;50&quot; type=&quot;string&quot; /&gt;

    &lt;bag name=&quot;albums&quot; cascade=&quot;all-delete-orphan&quot; inverse=&quot;true&quot; &gt;
      &lt;key column=&quot;ArtistId&quot;/&gt;
      &lt;one-to-many class=&quot;Album&quot; /&gt;
    &lt;/bag&gt;
  &lt;/class&gt;

  &lt;class entity-name=&quot;Album&quot;&gt;
    &lt;id name=&quot;id&quot; column=&quot;AlbumId&quot; type=&quot;int&quot;&gt;
      &lt;generator class=&quot;identity&quot;/&gt;
    &lt;/id&gt;

    &lt;property name=&quot;title&quot; length=&quot;50&quot; type=&quot;string&quot; not-null=&quot;true&quot; /&gt;
    &lt;many-to-one name=&quot;artist&quot; column=&quot;ArtistId&quot; not-null=&quot;true&quot; class=&quot;Artist&quot; /&gt;
  &lt;/class&gt;
</pre></div><p>And suppose we have the following 2 classes:</p><div><pre class="brush: ruby; title: ; notranslate">
class Artist
  attr_accessor :id, :name, :albums
  
  def initialize
    self.albums = System::Collections::ArrayList.new
  end
  
  def add_album(album)
    self.albums.add(album)
    album.artist = self
  end
  
  def remove_album(album)
    self.albums.remove(album)
    album.artist = nil
  end
end

class Album
  attr_accessor :id, :title, :artist
end
</pre></div><p>The only atypical thing about that Ruby code is the usage of System::Collections::ArrayList.  That's something i haven't been able to workaround yet: if you want to use collections, you'll need to use the .NET ones for now.</p><p>I'm relying on 2 things to get everything working.  One is NHibernate's Map EntityMode, the other is my own Ruby magic which i'll cover later.  The important thing to know is that the Map EntityMode basically works without classes, but with dictionaries.  Instead of instances of entity classes, NHibernate will return or accept dictionaries where the keys correspond to property names and the values correspond to their respective property's value.  Though the goal was that the developer need not use the dictionaries directly, as the above 2 Ruby classes show.  I'll get into the details of the Ruby magic later on in this post, but for now it's important to know that there's an ObjectFactory class which takes care of transforming the dictionaries that i get from NHibernate to either real instances of entity classes, or proxies of them.</p><p>First, let's take a look at transitive persistence:</p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        var artist = ruby.Artist.@new();
        artist.name = &quot;Rage Against The Machine&quot;;

        var album1 = ruby.Album.@new();
        album1.title = &quot;Rage Against The Machine&quot;;

        var album2 = ruby.Album.@new();
        album2.title = &quot;Evil Empire&quot;;

        artist.add_album(album1);
        artist.add_album(album2);

        session.Save(&quot;Artist&quot;, artist);

        session.Flush();

        artistId = artist.id();
    }
</pre></div><p>The output of running that code is this:</p><div><pre class="brush: plain; title: ; notranslate">
NHibernate: INSERT INTO Artist (name) VALUES (@p0); select SCOPE_IDENTITY();@p0 = 'Rage Against The Machine' [Type: String (50)]
NHibernate: INSERT INTO Album (title, ArtistId) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 'Rage Against The Machine' [Type: String (50)], @p1 = 355 [Type: Int32 (0)]
NHibernate: INSERT INTO Album (title, ArtistId) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 'Evil Empire' [Type: String (50)], @p1 = 355 [Type: Int32 (0)]
</pre></div><p>As you can see, transitive persistence is working nicely, even with collections.  Now let's see how we can retrieve that data from the database and into our Ruby objects.  First i need to show the following 2 helper methods for displaying the data:</p><div><pre class="brush: csharp; title: ; notranslate">
    private static void PrintArtistData(dynamic artist)
    {
        Console.WriteLine(&quot;Artist: &quot; + artist.name());
        PrintAlbumData(artist.albums());
    }

    private static void PrintAlbumData(dynamic albums)
    {
        foreach (dynamic album in albums)
        {
            Console.WriteLine(&quot;\tAlbum: &quot; + album.title());
        }
        Console.WriteLine();
    }
</pre></div><p>Now we can get the artist we just created with a simple call to session.Get:</p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        dynamic artist = ruby.ObjectFactory.create_from_nhibernate_hash(session.Get(&quot;Artist&quot;, artistId));
        Console.WriteLine(&quot;display output from session.Get&quot;);
        PrintArtistData(artist);
    }
</pre></div><p>And here's the output of that in the console:</p><div><pre class="brush: plain; title: ; notranslate">
NHibernate: SELECT artist0_.ArtistId as ArtistId0_0_, artist0_.name as name0_0_ FROM Artist artist0_ WHERE artist0_.ArtistId=@p0;@p0 = 355 [Type: Int32 (0)]
display output from session.Get
Artist: Rage Against The Machine
NHibernate: SELECT albums0_.ArtistId as ArtistId1_, albums0_.AlbumId as AlbumId1_, albums0_.AlbumId as AlbumId1_0_, albums0_.title as title1_0_, albums0_.ArtistId as ArtistId1_0_ FROM Album albums0_ WHERE albums0_.ArtistId=@p0;@p0 = 355 [Type: Int32 (0)]
        Album: Rage Against The Machine
        Album: Evil Empire
</pre></div><p>As you can see, the lazy loading of the albums collection works just as you'd expect it to.  Speaking of lazy-loading, we can do the same thing with a call to session.Load instead of session.Get:</p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        dynamic artist = ruby.ObjectFactory.create_proxy_from_nhibernate_hash(session.Load(&quot;Artist&quot;, artistId), &quot;Artist&quot;, artistId);
        Console.WriteLine(&quot;display output from session.Load&quot;);
        PrintArtistData(artist);
    }
</pre></div><p>As you may or may not know, session.Load returns a proxy of an entity instead of actually fetching it from the database immediately (unless the instance is already in the session cache, which my current ruby code can't handle yet).  NHibernate doesn't hit the database until you access any of the properties of the entity outside of the identifier, which the output of this code clearly shows:</p><div><pre class="brush: plain; title: ; notranslate">
display output from session.Load
NHibernate: SELECT artist0_.ArtistId as ArtistId0_0_, artist0_.name as name0_0_ FROM Artist artist0_ WHERE artist0_.ArtistId=@p0;@p0 = 355 [Type: Int32 (0)]
Artist: Rage Against The Machine
NHibernate: SELECT albums0_.ArtistId as ArtistId1_, albums0_.AlbumId as AlbumId1_, albums0_.AlbumId as AlbumId1_0_, albums0_.title as title1_0_, albums0_.ArtistId as ArtistId1_0_ FROM Album albums0_ WHERE albums0_.ArtistId=@p0;@p0 = 355 [Type: Int32 (0)]
        Album: Rage Against The Machine
        Album: Evil Empire
</pre></div><p>Notice that the select statement is outputted right before we access the name of the artist, instead of immediately as in the previous example.</p><p>We've got lazy-loading covered, but what about eager loading? Well, take a look at the following code:</p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        var artistHash = session.CreateCriteria(&quot;Artist&quot;)
            .Add(Restrictions.IdEq(artistId))
            .SetFetchMode(&quot;albums&quot;, FetchMode.Join)
            .List()[0];

        dynamic artist = ruby.ObjectFactory.create_from_nhibernate_hash(artistHash);
        Console.WriteLine(&quot;display output from session.CreateCriteria without any lazy loading&quot;);
        PrintArtistData(artist);
    }
</pre></div><p>This fetches our artist and immediately joins its albums in the same query.  When we access the albums of the artist, it no longer needs to go to the database:</p><div><pre class="brush: plain; title: ; notranslate">
NHibernate: SELECT this_.ArtistId as ArtistId0_1_, this_.name as name0_1_, albums2_.ArtistId as ArtistId3_, albums2_.AlbumId as AlbumId3_, albums2_.AlbumId as AlbumId1_0_, albums2_.title as title1_0_, albums2_.ArtistId as ArtistId1_0_ FROM Artist this_ left outer join Album albums2_ on this_.ArtistId=albums2_.ArtistId WHERE this_.ArtistId = @p0;@p0 = 355 [Type: Int32 (0)]
display output from session.CreateCriteria without any lazy loading
Artist: Rage Against The Machine
        Album: Rage Against The Machine
        Album: Evil Empire
</pre></div><p>Obviously, if we omit setting the fetchmode of the albums association we get the same output as we would get from using session.Get:</p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        var artistHash = session.CreateCriteria(&quot;Artist&quot;)
            .Add(Restrictions.IdEq(artistId))
            .List()[0];

        dynamic artist = ruby.ObjectFactory.create_from_nhibernate_hash(artistHash);
        Console.WriteLine(&quot;display output from session.CreateCriteria with lazy loading of albums&quot;);
        PrintArtistData(artist);
    }
</pre></div><div><pre class="brush: plain; title: ; notranslate">
NHibernate: SELECT this_.ArtistId as ArtistId0_0_, this_.name as name0_0_ FROM Artist this_ WHERE this_.ArtistId = @p0;@p0 = 355 [Type: Int32 (0)]
display output from session.CreateCriteria with lazy loading of albums
Artist: Rage Against The Machine
NHibernate: SELECT albums0_.ArtistId as ArtistId1_, albums0_.AlbumId as AlbumId1_, albums0_.AlbumId as AlbumId1_0_, albums0_.title as title1_0_, albums0_.ArtistId as ArtistId1_0_ FROM Album albums0_ WHERE albums0_.ArtistId=@p0;@p0 = 355 [Type: Int32 (0)]
        Album: Rage Against The Machine
        Album: Evil Empire
</pre></div><p>Eager fetching also works in the other direction, when fetching albums with their artist included automatically:</p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        var albumsList = session.CreateCriteria(&quot;Album&quot;)
            .CreateAlias(&quot;artist&quot;, &quot;a&quot;, JoinType.InnerJoin)
            .SetMaxResults(5)
            .List();

        dynamic albums = ruby.ObjectFactory.create_multiple_from_nhibernate_list(albumsList);

        foreach (dynamic album in albums)
        {
            Console.WriteLine(string.Format(&quot;'{0}' by '{1}'&quot;, album.title(), album.artist().name()));
        }
    }
</pre></div><p>This results in the following output:</p><div><pre class="brush: plain; title: ; notranslate">
NHibernate: SELECT TOP (@p0) this_.AlbumId as AlbumId1_1_, this_.title as title1_1_, this_.ArtistId as ArtistId1_1_, a1_.ArtistId as ArtistId0_0_, a1_.name as name0_0_ FROM Album this_ inner join Artist a1_ on this_.ArtistId=a1_.ArtistId;@p0 = 5 [Type: Int32 (0)]
'For Those About To Rock We Salute You 2' by 'Accept'
'Balls to the Wall' by 'Accept'
'Restless and Wild' by 'Accept'
'Let There Be Rock' by 'AC/DC'
'Big Ones' by 'Aerosmith'
</pre></div><p>Finally, we'll retrieve our artist and modify some of its data:</p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        dynamic artist = ruby.ObjectFactory.create_from_nhibernate_hash(session.Get(&quot;Artist&quot;, artistId));

        artist.name = &quot;RATM&quot;;
        artist.albums()[1].title = &quot;The Battle Of Los Angeles&quot;;

        artist.remove_album(artist.albums()[0]);

        dynamic newAlbum = ruby.Album.@new();
        newAlbum.title = &quot;Renegades&quot;;
        artist.add_album(newAlbum);

        session.Flush();
    }
</pre></div><p>If we then run the following code again:</p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        dynamic artist = ruby.ObjectFactory.create_from_nhibernate_hash(session.Get(&quot;Artist&quot;, artistId));
        Console.WriteLine(&quot;display output from session.Get&quot;);
        PrintArtistData(artist);
    }
</pre></div><p>We can see that the data has indeed been changed as it should:</p><div><pre class="brush: plain; title: ; notranslate">
NHibernate: SELECT artist0_.ArtistId as ArtistId0_0_, artist0_.name as name0_0_ FROM Artist artist0_ WHERE artist0_.ArtistId=@p0;@p0 = 355 [Type: Int32 (0)]
display output from session.Get
Artist: RATM
NHibernate: SELECT albums0_.ArtistId as ArtistId1_, albums0_.AlbumId as AlbumId1_, albums0_.AlbumId as AlbumId1_0_, albums0_.title as title1_0_, albums0_.ArtistId as ArtistId1_0_ FROM Album albums0_ WHERE albums0_.ArtistId=@p0;@p0 = 355 [Type: Int32 (0)]
        Album: The Battle Of Los Angeles
        Album: Renegades
</pre></div><p>Ok, so how does this all work? After all, NHibernate returns and expects dictionaries and as you can see in the code of the ruby classes, there are no dictionaries being used.  The answer is actually pretty simple.  NHibernate returns and expects dictionaries.  I return and expect entity instances.  Clearly, all we need to do is make sure that our entities pretend to be dictionaries and NHibernate will never need to know what on earth we're doing.</p><p>The first thing we need to do is to modify the implementation of the ruby classes that we have created for our entities.  Obviously, i wouldn't want anyone to have to do that manually, so my ruby magic just does this at runtime.  The only limit that is placed on the code you write in ruby is that within the entity classes, you can never touch the private instance fields of the attributes that you've defined.  You always have to go through the accessors.  Because of that limit, i can just replace all of the accessor methods with implementations that use the dictionary that NHibernate gives me as the backing store of the data instead of using instance fields.  I also make sure that all equality checks are based on the underlying dictionary instead of the actual object.  This passes everything but a straight-up reference check.  Finally, we need to make sure that our objects can be cast to an IDictionary and that we implement the indexer property of the IDictionary interface because NHibernate will use that when we pass it transient instances to insert into the database.</p><p>First, let's take a look at the ObjectFactory class, which has a couple of class methods that we use from our .NET code to create entities based on the dictionaries that we get from NHibernate:</p><div><pre class="brush: ruby; title: ; notranslate">
class ObjectFactory
  def self.create_from_nhibernate_hash(hashtable)
    entity_name = hashtable[NHibernator::TYPE_KEY_NAME.to_clr_string]
    entity = const_get(entity_name.to_sym).new
    entity.hydrate_from hashtable
    entity    
  end
  
  def self.create_proxy_from_nhibernate_hash(hashtable, entity_name, id)
    proxy = const_get(&quot;#{entity_name}Proxy&quot;.to_sym).new
    proxy.hydrate_from hashtable, id
    proxy
  end
  
  def self.create_multiple_from_nhibernate_list(list)
    entities = []
    # TODO: differentiate between proxies and normal entities in the list
    list.each { |hash| entities &lt;&lt; create_from_nhibernate_hash(hash) }
    entities
  end
end
</pre></div><p>(as you can see from the TODO statement, this whole thing is still a work in progress)</p><p>Pretty simple stuff so far... We either create a new instance of the entity class, or of a proxy class for that entity type (i'll cover the creation of proxy classes soon).  We then call its hydrate_from method, which is also added to each entity class dynamically.  There's another (temporary) limitation here... i search for the class name constant in Object, which means that our current approach doesn't work when our entities have namespaces.  Not really a problem for this example, and is easy to add later on when i actually need it.  That's it for the ObjectFactory... the real magic is all contained in the NHibernator module.  And no, i couldn't come up with a better name.  Long-time readers should know by now that i absolutely suck at coming up with good names so that's why we ended up with the NHibernator module.</p><p>The NHibernator module does 2 things: it offers a method that you need to use when initializing your application so we can create the proxy classes based on NHibernate's metadata, and it also modifies the accessor methods and adds some new methods whenever it is mixed in to another class.  I'm going to show the code of the NHibernator module in multiple steps to hopefully keep everything as clear as possible.  First of all, i'm gonna show the declaration of a constant and a simple helper method that we're going to need:</p><div><pre class="brush: ruby; title: ; notranslate">
  TYPE_KEY_NAME = &quot;$type$&quot;

  def self.each_writeable_accessor_of(klass, &amp;block)
    setters = klass.public_instance_methods(true).select { |name| name =~ /\w=$/ }
    setters.each { |setter| yield setter }
  end  
</pre></div><p>The TYPE_KEY_NAME constant contains the string that NHibernate uses as the key in its dictionaries for the value which returns the current entity's type name.  And the each_writeable_accessor_of method executes the given block for each writeable acessor that a class contains.</p><p>And this is how we initialize everything:</p><div><pre class="brush: ruby; title: ; notranslate">
  def self.initialize(session_factory)
    all_class_metadata = session_factory.get_all_class_metadata
    
    all_class_metadata.keys.each do |key|
      metadata = all_class_metadata[key]
      realclass = Object::const_get(key)
      realclass.send :include, NHibernator
      create_proxy_class_for realclass, metadata.identifier_property_name
    end
  end
  
  def self.create_proxy_class_for(klass, identifier_name)
    proxyclass = Class.new(klass)
    Object::const_set &quot;#{klass.name}Proxy&quot;, proxyclass
    
    proxyclass.class_eval do
      define_method identifier_name do
        @id
      end
      
      def hydrate_from(hashtable, id)
        @nhibernate_values = hashtable
        @id = id
      end
    end
    
    each_writeable_accessor_of(klass) do |setter|
      proxyclass.class_eval do
        define_method setter do |value|
          # execute the getter to force NH's lazy proxymap to fetch the data
          send setter.to_s.chop
          super value
        end
      end
    end
  end
</pre></div><p>The initialize class method takes an NHibernate ISessionFactory instance and retrieves each mapped entity with the information that we need about it.  Each mapped entity's class is sent the include message with the NHibernator module as a parameter.  This basically mixes in the functionality of the NHibernator module into each entity's class.  I'll discuss this in the next part of the post.  After we've mixed the module into the entity classes, we call the create_proxy_class_for method for each class.  As you can see, creating the proxy classes is very easy stuff.  Any proxy class that we create inherits from the class of the entity, and overrides the accessor method to retrieve the identifier value so that it immediately returns the identifier value.  If we would've kept the default implementation, it would access the dictionary that we got from NHibernate, which would cause a select statement for this proxy to be issued, which we obviously don't want.  Again, this is a work in progress and one limitation that this current proxy implementation has is that you'll get a reference to a dictionary instead of an entity when you access a reference-property of a proxy.  That too will be easy to fix <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Next up, we need to cover what happens when the NHibernator module is mixed into an entity class.  Ruby has a great hook method for that, which is this:</p><div><pre class="brush: ruby; title: ; notranslate">
  def self.include(base)
    # everything you do within this method will be executed whenever
    # this module is included in a class... the base parameter is
    # the class that included the module
    
    # ...
  end
</pre></div><p>I'm doing quite a bit within that method and i want to cover each item in detail.  So, the next couple of pieces of code are all part of the self.include(base) method implementation.  The first thing we do when this module gets included in a class is this:</p><div><pre class="brush: ruby; title: ; notranslate">
    each_writeable_accessor_of(base) do |setter|
      getter = setter.to_s.chop
      
      base.class_eval do
        undef_method getter
        undef_method setter
        
        define_method getter do
          return nil if @nhibernate_values.nil?
          value = @nhibernate_values[getter.to_clr_string]
          return value unless value.is_a? System::Collections::IEnumerable
          # TODO: cache the WrappedList instance
          WrappedList.new(value)
        end
        
        define_method setter do |value|
          @nhibernate_values = System::Collections::Hashtable.new if @nhibernate_values.nil?
          @nhibernate_values[setter.to_s.chop.to_clr_string] = value
        end
      end
    end
</pre></div><p>This is pretty simple, we're just getting rid of all of the original accessor methods and replacing them with our own implementations that use the dictionary we get from NHibernate as the backing store.  Note that i will discuss the WrappedList class that you see in those getters soon.  The setter methods will also instantiate a new Hashtable if we don't already have a dictionary.  This is necessary for transient instances since NHibernate will treat them as IDictionary instances when we pass them to the session.  Speaking of which, this is the next thing we do:</p><div><pre class="brush: ruby; title: ; notranslate">
    base.send :include, System::Collections::IDictionary
</pre></div><p>This single line enables any piece of .NET code to cast our instances to an IDictionary reference.  Note that we haven't even implemented any of the IDictionary interface's methods yet.  We don't need to implement all of them anyway, just the ones that we know will be used.</p><p>Finally, we add all of the following methods to each class that included this module:</p><div><pre class="brush: ruby; title: ; notranslate">
    base.class_eval do
      def nhibernate_values
        @nhibernate_values
      end

      def hydrate_from(hashtable)
        @nhibernate_values = hashtable
        referenced_entities = Hash.new

        hashtable.keys.each do |key|
          value = hashtable[key.to_clr_string]
                    
          if value.is_a? System::Collections::IDictionary
            if value.is_a? System::Collections::Hashtable
              referenced_entity = ObjectFactory.create_from_nhibernate_hash(value)
            else
              type = value.hibernate_lazy_initializer.entity_name
              id = value.hibernate_lazy_initializer.identifier
              referenced_entity = ObjectFactory.create_proxy_from_nhibernate_hash(value, type, id)
            end
          
            referenced_entities[key] = referenced_entity
          end
        end

        referenced_entities.keys.each { |key| send &quot;#{key}=&quot;, referenced_entities[key] }
      end
      
      def Equals(other)
        self == other
      end

      def GetHashCode
        hash
      end
            
      def ==(other)
        return false if other.nil?
        return @nhibernate_values.Equals(other) if other.is_a? System::Collections::IDictionary
        return false unless other.respond_to? :nhibernate_values
        other.nhibernate_values.Equals(@nhibernate_values)        
      end
            
      def hash
        @nhibernate_values.GetHashCode()
      end
                                                
      def [](key)
        self.send key
      end 

      def []=(key, value)
        self.send &quot;#{key}=&quot;, value
      end      
    end
</pre></div><p>I think that code speaks for itself, except for the Equals and GetHashCode methods... those are just there because i had some issues with IronRuby mapping calls to Equals or GetHashCode to their corresponding ruby alternatives (== and hash).  I eventually upgraded to the latest IronRuby revision from GitHub, because i didn't get correct results with the IronRuby 1.1 alpha 1 to get the equality checks working correctly.</p><p>Finally, i needed the following 2 helper classes to make the albums bag work correctly:</p><div><pre class="brush: ruby; title: ; notranslate">
class WrappedList
  include System::Collections::IList
  
  def initialize(list)
    @list = list  
  end
  
  def each(&amp;block)
    @list.each do |item|
      if item.respond_to? :nhibernate_values
        yield item
      else
        yield ObjectFactory.create_from_nhibernate_hash(item)
      end
    end
  end

  def GetEnumerator
    WrappedListEnumerator.new(self)
  end

  def add(item)
    @list.add item
  end
  
  def clear
    @list.clear
  end
  
  def contains(item)
    @list.contains item
  end
  
  def count
    @list.count
  end
  
  def remove(item)
    original_count = count
    if item.respond_to? :nhibernate_values
      @list.remove item.nhibernate_values
    else
      @list.remove item
    end
    original_count != count
  end
  
  def is_read_only
    @list.is_read_only
  end
  
  def index_of(item)
    @list.index_of item
  end
  
  def insert(index, item)
    @list.insert index, item
  end
  
  def remove_at(index)
    @list.remove_at index
  end
  
  def [](index)
    item = @list[index]
    return item if item.respond_to? :nhibernate_values
    ObjectFactory.create_from_nhibernate_hash(item)
  end
  
  def []=(index, item)
    @list[index] = item
  end
  
  def Equals(other)
    self == other
  end

  def GetHashCode
    hash
  end
            
  def ==(other)
    return false if other.nil?
    @list.Equals(other)
  end
        
  def hash
     GetHashCode
  end
end

class WrappedListEnumerator
  include System::Collections::IEnumerator
  
  def initialize(wrappedlist)
    @wrappedlist = wrappedlist
    reset
  end
  
  def reset
    @current_index = -1
  end
  
  def current
    @wrappedlist[@current_index]
  end
  
  def move_next
    @current_index += 1
    return false if @current_index &gt;= @wrappedlist.count
    true
  end
end
</pre></div><p>And that's all there is to it.  This is probably the longest blog post i've ever written, but the amount of code involved in getting this working really isn't that much.  Granted, there are still limitations to this approach so some stuff will need to be added to it.  I'm also not saying that this is actually a great idea or that you should start doing this from now on, but well, at least this is possible now <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F09%2Fusing-nhibernate-to-persist-and-query-ruby-objects%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/09/using-nhibernate-to-persist-and-query-ruby-objects/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/09/using-nhibernate-to-persist-and-query-ruby-objects/"  data-text="Using NHibernate To Persist And Query Ruby Objects" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/09/using-nhibernate-to-persist-and-query-ruby-objects/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/09/using-nhibernate-to-persist-and-query-ruby-objects/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/09/using-nhibernate-to-persist-and-query-ruby-objects/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Mad Scientist At Work</title><link>http://davybrion.com/blog/2010/09/mad-scientist-at-work/</link> <comments>http://davybrion.com/blog/2010/09/mad-scientist-at-work/#comments</comments> <pubDate>Wed, 08 Sep 2010 15:52:36 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[IronRuby]]></category> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Ruby]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2656</guid> <description><![CDATA[Just wanted to show some code, and yes, it actually works and I can't get property syntax working properly (as in: without requiring the parentheses) when accessing mapped properties due to an issue with IronRuby that needs to be fixed first, but other than that i'm pretty happy with how this works Full details will [...]]]></description> <content:encoded><![CDATA[<p>Just wanted to show some code, and yes, it actually works <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        var artist = ruby.ObjectFactory.CreateArtist();
        artist.Name = &quot;some name&quot;;
        session.Save(&quot;Artist&quot;, artist);
        session.Flush();
        // and this actually prints out the id of the artist (in this case, it's defined as an identity in sql server)
        Console.WriteLine(artist.ArtistId());
    }
</pre></div><p>and</p><div><pre class="brush: csharp; title: ; notranslate">
    using (var session = sessionFactory.OpenSession())
    {
        var albumId = 1;
        var artistId = 1;

        var album = ruby.ObjectFactory.create_from_nhibernate_hash(session.Get(&quot;Album&quot;, albumId));
        // the following line does NOT issue a select statement
        Console.WriteLine(album.Artist().ArtistId());
        // but this one obviously will trigger the lazy loading of the Artist instance
        Console.WriteLine(album.Artist().Name());

        var realArtist = ruby.ObjectFactory.create_from_nhibernate_hash(session.Get(&quot;Artist&quot;, artistId));

        album.Title = album.Title() + &quot; 2&quot;;
        realArtist.Name = realArtist.Name() + &quot; 2&quot;;

        if (album.Artist() == realArtist &amp;&amp; album.Artist().Name() == realArtist.Name())
        {
            // this actually persists the changes
            session.Flush();
        }
        else
        {
            throw new InvalidOperationException(&quot;The universe should collapse&quot;);
        }
    }
</pre></div><p>I can't get property syntax working properly (as in: without requiring the parentheses) when accessing mapped properties due to an <a
href="http://ironruby.codeplex.com/workitem/4920">issue </a> with IronRuby that needs to be fixed first, but other than that i'm pretty happy with how this works <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Full details will be posted once i've taken care of a few more things <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><p><img
src="http://davybrion.com/blog/wp-content/uploads/2010/09/Mad_scientist.gif" alt="" title="Mad_scientist" width="338" height="450" class="aligncenter size-full wp-image-2658" /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F09%2Fmad-scientist-at-work%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/09/mad-scientist-at-work/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/09/mad-scientist-at-work/"  data-text="Mad Scientist At Work" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/09/mad-scientist-at-work/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/09/mad-scientist-at-work/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/09/mad-scientist-at-work/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Think Twice Before You Map Entities To DTOs</title><link>http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/</link> <comments>http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/#comments</comments> <pubDate>Wed, 01 Sep 2010 11:58:32 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2607</guid> <description><![CDATA[One thing that i see a lot, and that i have largely started to avoid, is that people fetch entities with NHibernate, only to transform them to DTO's so you can send them back to the client so they can be displayed in a a grid or some kind of list or whatever. This is [...]]]></description> <content:encoded><![CDATA[<p>One thing that i see a lot, and that i have largely started to avoid, is that people fetch entities with NHibernate, only to transform them to DTO's so you can send them back to the client so they can be displayed in a a grid or some kind of list or whatever.  This is usually pretty easy to do, especially if you already have a DTO mapper or are using something like Automapper.  But this comes with a bit of overhead (both performance and memory) that you can often avoid quite easily.</p><p>Suppose i have a screen where i need to display entries based on the following DTO class:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class AuthorizationDto
    {
        public long Id { get; set; }
        public Guid ApplicationId { get; set; }
        public string ApplicationName { get; set; }
        public Guid? UserGroupId { get; set; }
        public string UserGroupName { get; set; }
        public Guid? UserId { get; set; }
        public string Username { get; set; }
        public Guid PermissionId { get; set; }
        public string PermissionName { get; set; }
        public string PermissionDescription { get; set; }
    }
</pre></div><p>This DTO basically contains data from 4 entities: Application, UserGroup, User and Permission.  I could easily do something like this with NHibernate:</p><div><pre class="brush: csharp; title: ; notranslate">
            var items = Session.CreateCriteria&lt;Authorization&gt;()
                .CreateAlias(&quot;Application&quot;, &quot;a&quot;, JoinType.InnerJoin)
                .CreateAlias(&quot;User&quot;, &quot;u&quot;, JoinType.LeftOuterJoin)
                .CreateAlias(&quot;UserGroup&quot;, &quot;g&quot;, JoinType.LeftOuterJoin)
                .CreateAlias(&quot;Permission&quot;, &quot;p&quot;, JoinType.InnerJoin)
                .Future&lt;Authorization&gt;();

            var dtos = new AuthorizationDtoMapper().ToDtos(items);
</pre></div><p>As you can see, that's very easy to do.  Unfortunately, this code really does a lot of stuff that you might not realize.  For starters, it retrieves all of the Authorization instances with its related Application, User, UserGroup and Permission instances.  It also fetches those entities in their entirety, which means it's retrieving all of their properties while i only need their Id and Name properties really.  And finally, NHibernate will set up all of the things that enable its magic for all of these entity instances.  That takes a few more CPU cycles and uses more memory than you truly need for the scenario of fetching entities merely to return DTO's.  This extra cost obviously becomes worse depending on the size of the resultset that you're fetching.</p><p>A better way to do this, is to simply let NHibernate fetch only the data (columns) that you need, and to let it populate the DTO's itself.  You can easily do this using projections and the AliasToBeanResultTransformer class.  The code would look like this:</p><div><pre class="brush: csharp; title: ; notranslate">
            var dtos = Session.CreateCriteria&lt;Authorization&gt;()
                .CreateAlias(&quot;Application&quot;, &quot;a&quot;, JoinType.InnerJoin)
                .CreateAlias(&quot;User&quot;, &quot;u&quot;, JoinType.LeftOuterJoin)
                .CreateAlias(&quot;UserGroup&quot;, &quot;g&quot;, JoinType.LeftOuterJoin)
                .CreateAlias(&quot;Permission&quot;, &quot;p&quot;, JoinType.InnerJoin)
                .SetProjection(Projections.ProjectionList()
                    .Add(Projections.Id(), &quot;Id&quot;)
                    .Add(Projections.Property(&quot;a.Id&quot;), &quot;ApplicationId&quot;)
                    .Add(Projections.Property(&quot;a.Name&quot;), &quot;ApplicationName&quot;)
                    .Add(Projections.Property(&quot;u.Id&quot;), &quot;UserId&quot;)
                    .Add(Projections.Property(&quot;u.UserName&quot;), &quot;Username&quot;)
                    .Add(Projections.Property(&quot;g.Id&quot;), &quot;UserGroupId&quot;)
                    .Add(Projections.Property(&quot;g.Name&quot;), &quot;UserGroupName&quot;)
                    .Add(Projections.Property(&quot;p.Id&quot;), &quot;PermissionId&quot;)
                    .Add(Projections.Property(&quot;p.Name&quot;), &quot;PermissionName&quot;)
                    .Add(Projections.Property(&quot;p.Description&quot;), &quot;PermissionDescription&quot;))
                .SetResultTransformer(new AliasToBeanResultTransformer(typeof(AuthorizationDto)))
                .Future&lt;AuthorizationDto&gt;();
</pre></div><p>Granted, you need to write a bit more code.  But that code will do far less than the first version.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F09%2Fthink-twice-before-you-map-entities-to-dtos%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/"  data-text="Think Twice Before You Map Entities To DTOs" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/feed/</wfw:commentRss> <slash:comments>20</slash:comments> </item> <item><title>Avoiding Leaking Connections With NHibernate And TransactionScope</title><link>http://davybrion.com/blog/2010/05/avoiding-leaking-connections-with-nhibernate-and-transactionscope/</link> <comments>http://davybrion.com/blog/2010/05/avoiding-leaking-connections-with-nhibernate-and-transactionscope/#comments</comments> <pubDate>Thu, 06 May 2010 12:16:31 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[MSDTC]]></category> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2010/05/avoiding-leaking-connections-with-nhibernate-and-transactionscope/</guid> <description><![CDATA[One of the applications we’re currently working on wasn’t responding anymore on the development server.&#160; The logfile showed the following message: System.InvalidOperationException: Timeout expired.&#160; The timeout period elapsed prior to obtaining a connection from the pool.&#160; This may have occurred because all pooled connections were in use and max pool size was reached. We’ve been [...]]]></description> <content:encoded><![CDATA[<p>One of the applications we’re currently working on wasn’t responding anymore on the development server.&#160; The logfile showed the following message:</p><blockquote><p>System.InvalidOperationException: Timeout expired.&#160; The timeout period elapsed prior to obtaining a connection from the pool.&#160; This may have occurred because all pooled connections were in use and max pool size was reached.</p></blockquote><p>We’ve been using NHibernate in almost all of our projects for about 2 years now and we’ve never had this issue before.&#160; The thing is though, we never used System.Transactions’ TransactionScope class before and always used NHibernate’s transactions directly.&#160; In this project, we’re using TransactionScope for the first time (mostly because we need distributed transactions occasionally) so i immediately suspected that we were either doing something wrong with it, or that there was a bug somewhere.</p><p>After a while i managed to reproduce the problem with the following simple test fixture:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; [<span
style="color: #2b91af">TestFixture</span>]</p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">ConnectionLeakTest</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">static</span> <span
style="color: #2b91af">ISessionFactory</span> sessionFactory;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">static</span> ConnectionLeakTest()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactory = <span
style="color: blue">new</span> <span
style="color: #2b91af">Configuration</span>()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .Configure()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .AddAssembly(<span
style="color: #a31515">&quot;MyAssembly&quot;</span>)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .BuildSessionFactory();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">Test</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> LeaksConnection()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> counter = 11;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">for</span> (<span
style="color: blue">int</span> i = 0; i &lt; counter; i++)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">using</span> (<span
style="color: blue">var</span> scope = <span
style="color: blue">new</span> <span
style="color: #2b91af">TransactionScope</span>(<span
style="color: #2b91af">TransactionScopeOption</span>.Required))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">using</span> (<span
style="color: blue">var</span> session = sessionFactory.OpenSession())</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> blah = session.CreateCriteria&lt;<span
style="color: #2b91af">User</span>&gt;().List&lt;<span
style="color: #2b91af">User</span>&gt;();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>If you assign counter a value that is greater than your ‘Max Pool Size’ value of your connection string, then you will get the following exception once you’re going through the loop for the ‘Max Pool Size’ + 1 time:</p><blockquote><p>System.InvalidOperationException : Timeout expired.&#160; The timeout period elapsed prior to obtaining a connection from the pool.&#160; This may have occurred because all pooled connections were in use and max pool size was reached.</p></blockquote><p>Bingo!</p><p>In normal situations, you would obviously call the Complete method of the TransactionScope instance before it is disposed to commit the current database transaction.&#160; But in a situation where you can’t call the Complete method (as in: when an exception has occurred and you want to rollback the transaction), your database connection will actually leak until you’ve used up all of the connections in your connection pool.&#160;</p><p>So the question is: How can we use a TransactionScope with NHibernate without leaking connections when we throw an exception (which should result in an automatic rollback of the current transaction)?&#160;</p><p>I was always under the impression that merely opening an NHibernate session within a transaction scope was actually OK and that the session’s connection would make use of the current ambient transaction (the one created by the outer TransactionScope).&#160; Pretty much every session-related action you perform in NHibernate results in calling the CheckAndUpdateSessionStatus method of the SessionImpl class, which in turn calls the EnlistInAmbientTransactionIfNeeded method.&#160; That (as you can probably guess) will automatically enlist the current NHibernate session in the ambient transaction, which is the one that was created by the TransactionScope.&#160; So, as i understand it, it should indeed be sufficient to open an NHibernate session within a TransactionScope to have every action performed by that session being enlisted in the current ambient transaction.&#160;&#160; And it actually behaves as transactional as you’d expect it to be.&#160; Your transaction is properly committed if you call the Complete method of the TransactionScope and it is indeed rolled back if you do not call the Complete method.&#160; The only problem (and it’s a major one obviously) is that you’re connection will leak when the transaction is rolled back.&#160;</p><p>Interestingly enough, if we change the test code to this:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">Test</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> LeaksConnection()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> counter = 11;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">for</span> (<span
style="color: blue">int</span> i = 0; i &lt; counter; i++)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">using</span> (<span
style="color: blue">var</span> scope = <span
style="color: blue">new</span> <span
style="color: #2b91af">TransactionScope</span>(<span
style="color: #2b91af">TransactionScopeOption</span>.Required))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">using</span> (<span
style="color: blue">var</span> session = sessionFactory.OpenSession())</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">using</span> (<span
style="color: blue">var</span> transaction = session.BeginTransaction())</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> blah = session.CreateCriteria&lt;<span
style="color: #2b91af">User</span>&gt;().List&lt;<span
style="color: #2b91af">User</span>&gt;();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; transaction.Rollback();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Then the problem goes away.&#160; Transactions are correctly rolled back, and none of the connections leak anymore.&#160; It’s too bad that we still need to use NHibernate’s transactions only for the sake of being able to rollback in case of failure without leaking the connection, because again, when you’re not using an NHibernate transaction but are within a TransactionScope, your Session’s connection will indeed be enlisted in the transaction being governed by the TransactionScope.&#160; So there certainly appears to be some kind of bug in NHibernate when it comes to cleaning up the connection of a session that has been enlisted in a TransactionScope’s transaction which is rolled back instead of committed.</p><p>Now, since i frequently see people on the intarweb showing examples of using an NHibernate session together with a TransactionScope yet without using an NHibernate transaction, i’d might as well post the way that i believe is the safest, and that shouldn’t leak any connections.</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">using</span> (<span
style="color: blue">var</span> scope = <span
style="color: blue">new</span> <span
style="color: #2b91af">TransactionScope</span>(<span
style="color: #2b91af">TransactionScopeOption</span>.Required))</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">using</span> (<span
style="color: blue">var</span> session = sessionFactory.OpenSession())</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">using</span> (<span
style="color: blue">var</span> transaction = session.BeginTransaction())</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: green">// do what you need to do with the session</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; transaction.Commit();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; scope.Complete();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p></div><p>&#160;</p><p>If you need to rollback, simply throw an exception within the using block of the NHibernate transaction (before the transaction.Commit() call obviously) and everything takes care of itself.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F05%2Favoiding-leaking-connections-with-nhibernate-and-transactionscope%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/05/avoiding-leaking-connections-with-nhibernate-and-transactionscope/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/05/avoiding-leaking-connections-with-nhibernate-and-transactionscope/"  data-text="Avoiding Leaking Connections With NHibernate And TransactionScope" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/05/avoiding-leaking-connections-with-nhibernate-and-transactionscope/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/05/avoiding-leaking-connections-with-nhibernate-and-transactionscope/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/05/avoiding-leaking-connections-with-nhibernate-and-transactionscope/feed/</wfw:commentRss> <slash:comments>31</slash:comments> </item> <item><title>MSDTC Woes With NServiceBus And NHibernate</title><link>http://davybrion.com/blog/2010/03/msdtc-woes-with-nservicebus-and-nhibernate/</link> <comments>http://davybrion.com/blog/2010/03/msdtc-woes-with-nservicebus-and-nhibernate/#comments</comments> <pubDate>Fri, 19 Mar 2010 10:52:16 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[.NET bugs]]></category> <category><![CDATA[MSDTC]]></category> <category><![CDATA[NHibernate]]></category> <category><![CDATA[nservicebus]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2010/03/msdtc-woes-with-nservicebus-and-nhibernate/</guid> <description><![CDATA[I’ve spent about 3 days trying to get something working that should’ve just worked.&#160; I basically wanted some .NET code to use a distributed transaction to update some data in a database, and then publish a message on the service bus.&#160; I want to do this in a distributed transaction because if something goes wrong, [...]]]></description> <content:encoded><![CDATA[<p>I’ve spent about 3 days trying to get something working that should’ve just worked.&#160; I basically wanted some .NET code to use a distributed transaction to update some data in a database, and then publish a message on the service bus.&#160; I want to do this in a distributed transaction because if something goes wrong, i want to roll back both transactions (the database change and the published message).&#160; Normally, this should just work if you have MS DTC configured correctly.&#160; On my machine, i enabled Network DTC Access, and allowed outbound transaction communication.&#160; On the database server, Network DTC Access was already enabled and both outbound and inbound communication was allowed.&#160;</p><p>Now the thing is, i’d either expect DTC to fail outright or to just work.&#160; But it shouldn’t fail in one situation, and work in another.&#160; On my machine, it failed in the following situation (which i’ll further refer to as Situation A):</p><ol><li>open a transaction scope</li><li>open an nhibernate session</li><li>hit the db</li><li>publish a message through nservicebus</li><li>close the nhibernate session</li><li>complete and close the transaction scope</li></ol><p>Step 4 and 5 could be switched around but it didn’t make a difference.&#160; In Situation A, i always got a TransactionManagerCommunicationException with the following message:</p><blockquote><p>Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.</p></blockquote><p>Everyone who’s worked with MSDTC before probably knows that exception since it usually takes some fiddling with the settings to make things work.&#160; The thing is, i was pretty sure that my settings, as well as the ones on the database server were correct.&#160; Unfortunately, DTCPing didn’t confirm that since that too failed.</p><p>However, i also tried the following sequence of events (Situation B):</p><ol><li>open a transaction scope</li><li>open an nhibernate session</li><li>publish a message</li><li>hit the db</li><li>close the nhibernate session</li><li>complete and close the transaction scope</li></ol><p>And guess what.&#160; That actually worked.&#160; With full DTC transaction semantics.&#160; The DTC statistics on the server confirmed that it was indeed using a DTC transaction, and if i made the code fail with an exception both the database action and the published message were correctly rolled back.</p><p>So the question is: why on earth does it only work when i publish a message before i hit the db?</p><p>During my investigation i noticed that in Situation A, the internal transaction that the transaction scope was using was a SqlDelegatedTransaction.&#160; Which, if i’m not mistaken is an LTM transaction.&#160; When trying to send a message to a message queue, the transaction manager tries to promote the current transaction to an OletxCommittableTransaction since the OleTx transaction protocol is required when using MSMQ (it doesn’t support LTM transactions).&#160; For some reason, promoting the SqlDelegatedTransaction to a full DTC (OleTx) transaction fails on my machine.</p><p>In Situation B, the internal transaction is promoted to an OletxCommittableTransaction as soon as you try to send the message to a message queue.&#160; Once it’s time to hit the DB, NHibernate nicely works together with the OletxCommittableTransaction and everything just works.</p><p>Now, i have no idea on earth why promotion of a SqlDelegatedTransaction fails, but after a long number of attempts and experiments to get it working correctly, i sorta gave up and figured i’d have to resort to a hack.&#160; What i basically needed was for the transaction scope’s internal transaction to automatically be promoted to an OletxCommittableTransaction <em>before<strong> </strong></em>i’d hit the database and without having to publish a dummy message at the beginning of the transaction.</p><p>I found one way of doing this which, while being a huge hack, is still relatively clean i think.&#160; I wrote the following class:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">DummyEnlistmentNotification</span> : <span
style="color: #2b91af">IEnlistmentNotification</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">static</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">Guid</span> Id = <span
style="color: blue">new</span> <span
style="color: #2b91af">Guid</span>(<span
style="color: #a31515">&quot;E2D35055-4187-4ff5-82A1-F1F161A008D0&quot;</span>);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> Prepare(<span
style="color: #2b91af">PreparingEnlistment</span> preparingEnlistment)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; preparingEnlistment.Prepared();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> Commit(<span
style="color: #2b91af">Enlistment</span> enlistment)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; enlistment.Done();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> Rollback(<span
style="color: #2b91af">Enlistment</span> enlistment)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; enlistment.Done();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> InDoubt(<span
style="color: #2b91af">Enlistment</span> enlistment)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; enlistment.Done();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Then, right after opening the transaction scope and before doing anything else, i do this:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: #2b91af">Transaction</span>.Current.EnlistDurable(<span
style="color: #2b91af">DummyEnlistmentNotification</span>.Id, <span
style="color: blue">new</span> <span
style="color: #2b91af">DummyEnlistmentNotification</span>(), <span
style="color: #2b91af">EnlistmentOptions</span>.None);</p></div><p>&#160;</p><p>This basically tells the System.Transactions infrastructure that we’re adding our own Resource Manager to the current transaction.&#160; And because it’s a durable Resource Manager, it now automatically promotes the internal transaction to an OletxCommittableTransaction and everything just works.&#160; While our Resource Manager participates in the 2-phase-commit process, it doesn’t actually do anything.&#160; It’s sole purpose is to force the creation of an OletxCommittableTransaction.</p><p>Like i said, it’s a hack but it’s still relatively clean.&#160; I still have no idea why i needed to resort to this hack though… If anyone can shed some light on this, i’d highly appreciate it <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Also, if you ever want to learn more about transactions in .NET or distributed transactions in particular, you really need to check out <a
href="http://www.codeproject.com/KB/WCF/NETTx.aspx" target="_blank">this article</a>.&#160; Without it, i probably wouldn’t have figured out what to do <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F03%2Fmsdtc-woes-with-nservicebus-and-nhibernate%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/03/msdtc-woes-with-nservicebus-and-nhibernate/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/03/msdtc-woes-with-nservicebus-and-nhibernate/"  data-text="MSDTC Woes With NServiceBus And NHibernate" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/03/msdtc-woes-with-nservicebus-and-nhibernate/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/03/msdtc-woes-with-nservicebus-and-nhibernate/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/03/msdtc-woes-with-nservicebus-and-nhibernate/feed/</wfw:commentRss> <slash:comments>19</slash:comments> </item> <item><title>Using NHibernate In Your Service Layer</title><link>http://davybrion.com/blog/2009/12/using-nhibernate-in-your-service-layer/</link> <comments>http://davybrion.com/blog/2009/12/using-nhibernate-in-your-service-layer/#comments</comments> <pubDate>Fri, 11 Dec 2009 12:53:36 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2036</guid> <description><![CDATA[I have an old post where i discuss how you can manage your NHibernate sessions in a service layer scenario.&#160; Now, the example of the service layer code in that post was pretty poor and people were asking for a better example.&#160; Hopefully, this post will do a better job at making sure everything is [...]]]></description> <content:encoded><![CDATA[<p>I have an old <a
href="http://davybrion.com/blog/2008/06/managing-your-nhibernate-sessions/" target="_blank">post</a> where i discuss how you can manage your NHibernate sessions in a service layer scenario.&#160; Now, the example of the service layer code in that post was pretty poor and people were asking for a better example.&#160; Hopefully, this post will do a better job at making sure everything is clear <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>First of all, the idea is to make sure that managing the NHibernate session (creating it, starting a transaction, committing or rolling back the transaction and closing the session) is taken care of automatically so you no longer have to worry about it.&#160; I also want to avoid passing the NHibernate session around all the time.&#160; This means that it will be created automatically when a request is sent to your service layer and stored in some place that will keep the instance alive during the handling of the service layer request.&#160; Every class that needs a reference to the current session (ideally only classes that deal purely with data access) will be able to retrieve it very easily, all in a thread-safe manner that can never be influenced by other concurrent requests.</p><p>First of all, you need something to wrap NHibernate’s ISessionFactory.&#160; I use the ISessionProvider for that:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">interface</span> <span
style="color: #2b91af">ISessionProvider</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">ISession</span> Create();</p><p
style="margin: 0px">&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">SessionProvider</span> : <span
style="color: #2b91af">ISessionProvider</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">ISessionFactory</span> sessionFactory;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> SessionProvider(<span
style="color: blue">string</span> mappingAssemblyName)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Configuration</span> configuration = <span
style="color: blue">new</span> <span
style="color: #2b91af">Configuration</span>()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .Configure()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .AddAssembly(mappingAssemblyName);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactory = configuration.BuildSessionFactory();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: #2b91af">ISession</span> Create()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> sessionFactory.OpenSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>In my case, i configure the IOC container to pass the name of the assembly that contains the mappings to the constructor of the SessionProvider class.&#160; If you’re using this code directly in your application, you could just as well hardcode the name of the assembly here.</p><p>You’ll also need something that allows you to store and retrieve the NHibernate session for the duration of the current request.&#160; I use the IActiveSessionManager for that:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">interface</span> <span
style="color: #2b91af">IActiveSessionManager</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">ISession</span> GetActiveSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">void</span> SetActiveSession(<span
style="color: #2b91af">ISession</span> session);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">void</span> ClearActiveSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">bool</span> HasActiveSession { <span
style="color: blue">get</span>; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">ActiveSessionManager</span> : <span
style="color: #2b91af">IActiveSessionManager</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">const</span> <span
style="color: blue">string</span> sessionKey = <span
style="color: #a31515">&quot;_currentSession&quot;</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">IRequestState</span> requestState;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> ActiveSessionManager(<span
style="color: #2b91af">IRequestState</span> requestState)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.requestState = requestState;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: #2b91af">ISession</span> GetActiveSession()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (Current == <span
style="color: blue">null</span>)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">throw</span> <span
style="color: blue">new</span> <span
style="color: #2b91af">InvalidOperationException</span>(<span
style="color: #a31515">&quot;There is no active ISession instance for this thread&quot;</span>);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> Current;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> SetActiveSession(<span
style="color: #2b91af">ISession</span> session)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (Current != <span
style="color: blue">null</span>)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">throw</span> <span
style="color: blue">new</span> <span
style="color: #2b91af">InvalidOperationException</span>(<span
style="color: #a31515">&quot;There is already an active ISession instance for this thread&quot;</span>);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Current = session;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> ClearActiveSession()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Current = <span
style="color: blue">null</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">bool</span> HasActiveSession</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">get</span> { <span
style="color: blue">return</span> Current != <span
style="color: blue">null</span>; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">virtual</span> <span
style="color: #2b91af">ISession</span> Current</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">get</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> requestState.Get&lt;<span
style="color: #2b91af">ISession</span>&gt;(sessionKey);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">set</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; requestState.Store(sessionKey, <span
style="color: blue">value</span>);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>This class will store the ISession instance in the <a
href="http://davybrion.com/blog/2009/01/abstracting-request-state/" target="_blank">current request state</a> (definitely click on that link if you don’t know IRequestState yet).</p><p>Now we can create our own Unit Of Work.&#160; This is not a pure Unit Of Work because it doesn’t do any change tracking or anything like that, but it does take care of creating an NHibernate session (which <em>does</em> do change tracking and anything that a real Unit Of Work should do) and cleaning it up when the Unit Of Work is completed.&#160; Here’s my implementation:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">interface</span> <span
style="color: #2b91af">IUnitOfWork</span> : <span
style="color: #2b91af">IDisposable</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">void</span> Clear();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">void</span> Flush();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">ITransaction</span> CreateTransaction();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">ITransaction</span> CreateTransaction(<span
style="color: #2b91af">IsolationLevel</span> isolationLevel);</p><p
style="margin: 0px">&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">UnitOfWork</span> : <span
style="color: #2b91af">Disposable</span>, <span
style="color: #2b91af">IUnitOfWork</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">IActiveSessionManager</span> sessionManager;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">ISession</span> session;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: blue">bool</span> isRootUnitOfWork;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> UnitOfWork(<span
style="color: #2b91af">ISessionProvider</span> sessionProvider, <span
style="color: #2b91af">IActiveSessionManager</span> sessionManager)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.sessionManager = sessionManager;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (sessionManager.HasActiveSession)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; isRootUnitOfWork = <span
style="color: blue">false</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session = sessionManager.GetActiveSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">else</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; isRootUnitOfWork = <span
style="color: blue">true</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session = sessionProvider.Create();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionManager.SetActiveSession(session);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> Clear()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Clear();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> Flush()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Flush();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: #2b91af">ITransaction</span> CreateTransaction()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> CreateTransaction(<span
style="color: #2b91af">IsolationLevel</span>.ReadCommitted);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: #2b91af">ITransaction</span> CreateTransaction(<span
style="color: #2b91af">IsolationLevel</span> isolationLevel)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (session.Transaction != <span
style="color: blue">null</span> &amp;&amp; session.Transaction.IsActive)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">throw</span> <span
style="color: blue">new</span> <span
style="color: #2b91af">InvalidOperationException</span>(<span
style="color: #a31515">&quot;nested transactions are not supported!&quot;</span>);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> session.BeginTransaction(isolationLevel);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">override</span> <span
style="color: blue">void</span> DisposeManagedResources()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (isRootUnitOfWork)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (session != <span
style="color: blue">null</span>)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Close();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Dispose();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionManager.ClearActiveSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>The idea is very simple.&#160; When the Unit Of Work is created, it asks the IActiveSessionManager if there is already an active session available.&#160; If not, it will create a new session through the ISessionProvider, and store it as the active session through the IActiveSessionManager.&#160; In the old implementation, the Unit Of Work would automatically create a new session in the constructor, but this obviously causes problems if you want to reuse a certain request handler from another request handler if they both depend on a IUnitOfWork instance.&#160;&#160; The IUnitOfWork interface doesn’t expose a lot of functionality but it’s all you need to <em>manage</em> your session in your service layer.&#160; It gives you the ability to create a transaction, clear the session and flush the session.&#160; When the IUnitOfWork is disposed, it will clean up the session and instruct the IActiveSessionManager to get rid of the session for this request.&#160;</p><p>Once you have this, you have all you need to prepare your service layer to take care of NHibernate session management automatically.&#160; I’m going to base the following service layer code example on Agatha (just because i think it’s the easiest way to implement a service layer <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ) but you can do exactly the same in your service layer.&#160; The important part is that you should configure your IOC container to inject a new instance of IUnitOfWork into the class that handles your service request.&#160; When the container injects the new instance, the NHibernate session will be created and stored in the IActiveSessionManager so there’s no more reason why you would have to do this yourself.</p><p>Now, i use the following class as the base class for all my request handlers that need NHibernate support:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">abstract</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">NhRequestHandler</span>&lt;TRequest, TResponse&gt; : <span
style="color: #2b91af">RequestHandler</span>&lt;TRequest, TResponse&gt;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">where</span> TRequest : <span
style="color: #2b91af">Request</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">where</span> TResponse : <span
style="color: #2b91af">Response</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: #2b91af">IUnitOfWork</span> UnitOfWork { <span
style="color: blue">get</span>; <span
style="color: blue">set</span>; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">override</span> <span
style="color: blue">void</span> DisposeManagedResources()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (UnitOfWork != <span
style="color: blue">null</span>) UnitOfWork.Dispose();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">override</span> <span
style="color: #2b91af">Response</span> Handle(<span
style="color: #2b91af">Request</span> request)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">using</span> (<span
style="color: #2b91af">ITransaction</span> transaction = UnitOfWork.CreateTransaction())</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Response</span> response;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">try</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; response = <span
style="color: blue">base</span>.Handle(request);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; transaction.Commit();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">catch</span> (<span
style="color: #2b91af">Exception</span> handlerException)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; transaction.Rollback();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">throw</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> response;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>(Note: the real implementation contains a bit more logging but other than that this is the real thing)</p><p>If you don’t understand the whole request handling concept, please check out <a
href="http://davybrion.com/blog/2009/11/requestresponse-service-layer-series/" target="_blank">the first 3 posts in this series</a>.&#160; Regardless of whether you’re using Agatha, your own Request/Response Service Layer or a classic (dare i say old-school?) service layer, the idea should be the same.&#160; Make sure this code is centralized in one place so you don’t have to repeat yourself all over your service layer code.&#160;&#160; Btw, in this case the IUnitOfWork instance is injected by the IOC container through Setter Injection instead of Constructor Injection.&#160; I’ve already discussed the reasons on why i prefer Setter Injection in this case <a
href="http://davybrion.com/blog/2009/11/constructor-injection-vs-sette-injection/" target="_blank">here</a>.</p><p>Now, you’re going to have some classes that will need to use an ISession instance to perform their tasks.&#160; I always create Repository classes for that, but the following approach would be similar for any other type of class which needs an ISession.&#160;&#160; Call them Data Access Objects, Data Access Classes or Sloppy Joes for all i care.&#160;&#160; Whatever you call these classes, they need a dependency on the IActiveSessionManager.&#160;&#160; Simply declare the IActiveSessionManager to be a dependency of your Sloppy Joe, i mean, Repository or DAO or whatever, like this:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">Repository</span>&lt;T&gt; : <span
style="color: #2b91af">IRepository</span>&lt;T&gt;</p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">IActiveSessionManager</span> activeSessionManager;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> Repository(<span
style="color: #2b91af">IActiveSessionManager</span> activeSessionManager)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.activeSessionManager = activeSessionManager;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: #2b91af">ISession</span> Session</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">get</span> { <span
style="color: blue">return</span> activeSessionManager.GetActiveSession(); }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Now you can write request handlers like this:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">GetCustomersRequestHandler</span> : <span
style="color: #2b91af">NhRequestHandler</span>&lt;<span
style="color: #2b91af">GetCustomersRequest</span>, <span
style="color: #2b91af">GetCustomersResponse</span>&gt;</p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">IRepository</span>&lt;<span
style="color: #2b91af">Customer</span>&gt; repository;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> GetCustomersRequestHandler(<span
style="color: #2b91af">IRepository</span>&lt;<span
style="color: #2b91af">Customer</span>&gt; repository)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">this</span>.repository = repository;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">override</span> <span
style="color: #2b91af">Response</span> Handle(<span
style="color: #2b91af">GetCustomersRequest</span> request)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> response = CreateTypedResponse();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; response.Customers = ConvertToDtos(repository.FindAll(request.Criteria));</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> response;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: #2b91af">CustomerDto</span>[] ConvertToDtos(<span
style="color: #2b91af">IEnumerable</span>&lt;<span
style="color: #2b91af">Customer</span>&gt; customers)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: green">// ...</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Obviously, this is a simple example but it works just as well for complex request handlers.&#160; Your NHibernate session is created and cleaned up automatically, without you having to write that code every single time. Each request handler will run in a transaction, and it will be committed or rolled back automatically without you having to do anything for it.&#160; And you only need to access the ISession instance in your Sloppy Joes.</p><p>Also keep in mind that you can also use the the ISessionProvider, IActiveSessionManager and IUnitOfWork in a purely web-based scenario as well if you want to.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F12%2Fusing-nhibernate-in-your-service-layer%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/12/using-nhibernate-in-your-service-layer/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/12/using-nhibernate-in-your-service-layer/"  data-text="Using NHibernate In Your Service Layer" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/12/using-nhibernate-in-your-service-layer/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/12/using-nhibernate-in-your-service-layer/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/12/using-nhibernate-in-your-service-layer/feed/</wfw:commentRss> <slash:comments>30</slash:comments> </item> <item><title>Testing CRUD Operations With NHibernate</title><link>http://davybrion.com/blog/2009/12/testing-crud-operations-with-nhibernate/</link> <comments>http://davybrion.com/blog/2009/12/testing-crud-operations-with-nhibernate/#comments</comments> <pubDate>Mon, 07 Dec 2009 11:38:02 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[testing]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2015</guid> <description><![CDATA[I was asked to show how you can easily do CRUD tests, so here’s a base class that makes it very easy &#160;&#160;&#160; public abstract class CrudTest&#60;TEntity, TId&#62; : NHibernateTest &#160;&#160;&#160;&#160;&#160;&#160;&#160; where TEntity : IHaveAnId&#60;TId&#62; &#160;&#160;&#160; { &#160;&#160;&#160;&#160;&#160;&#160;&#160; [Test] &#160;&#160;&#160;&#160;&#160;&#160;&#160; public virtual void SelectQueryWorks() &#160;&#160;&#160;&#160;&#160;&#160;&#160; { &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.CreateCriteria(typeof(TEntity)).SetMaxResults(5).List(); &#160;&#160;&#160;&#160;&#160;&#160;&#160; } &#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160; [Test] &#160;&#160;&#160;&#160;&#160;&#160;&#160; public [...]]]></description> <content:encoded><![CDATA[<p>I was <a
href="http://davybrion.com/blog/2009/12/unit-testing-an-nhibernate-application/comment-page-1/#comment-23096" target="_blank">asked</a> to show how you can easily do CRUD tests, so here’s a base class that makes it very easy</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">abstract</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">CrudTest</span>&lt;TEntity, TId&gt; : <span
style="color: #2b91af">NHibernateTest</span></p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">where</span> TEntity : <span
style="color: #2b91af">IHaveAnId</span>&lt;TId&gt;</p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">Test</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> SelectQueryWorks()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.CreateCriteria(<span
style="color: blue">typeof</span>(TEntity)).SetMaxResults(5).List();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">Test</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> AddEntity_EntityWasAdded()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> entity = BuildEntity();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InsertEntity(entity);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Evict(entity);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> reloadedEntity = session.Get&lt;TEntity&gt;(entity.Id);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Assert</span>.IsNotNull(reloadedEntity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssertAreEqual(entity, reloadedEntity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssertValidId(reloadedEntity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">Test</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> UpdateEntity_EntityWasUpdated()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> entity = BuildEntity();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InsertEntity(entity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ModifyEntity(entity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; UpdateEntity(entity);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Evict(entity);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> reloadedEntity = session.Get&lt;TEntity&gt;(entity.Id);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Assert</span>.IsNotNull(reloadedEntity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssertAreEqual(entity, reloadedEntity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">Test</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> DeleteEntity_EntityWasDeleted()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> entity = BuildEntity();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InsertEntity(entity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DeleteEntity(entity);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: #2b91af">Assert</span>.IsNull(session.Get&lt;TEntity&gt;(entity.Id));</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> InsertEntity(TEntity entity)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Save(entity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Flush();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> UpdateEntity(TEntity entity)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Update(entity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Flush();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> DeleteEntity(TEntity entity)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Delete(entity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.Flush();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">abstract</span> TEntity BuildEntity();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">abstract</span> <span
style="color: blue">void</span> ModifyEntity(TEntity entity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">abstract</span> <span
style="color: blue">void</span> AssertAreEqual(TEntity expectedEntity, TEntity actualEntity);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">abstract</span> <span
style="color: blue">void</span> AssertValidId(TEntity entity);</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Simply inherit from this class, implement the BuildEntity, ModifyEntity, AssertAreEqual and AssertValidId methods and that’s it.&#160; Those methods are usually pretty simple.&#160; In BuildEntity you just create an <em>unpersisted</em> entity and assign values to the properties, in ModifyEntity you modify the properties, and in AssertAreEqual you compare the properties of both instances.&#160; In AssertValidId, you make sure that the ID value is ok (depending on your identifier strategy).</p><p>This is good for regular CRUD operations, though we typically add extra tests when we want to test cascades or one-to-many associations mapped with inverse=”true”.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F12%2Ftesting-crud-operations-with-nhibernate%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/12/testing-crud-operations-with-nhibernate/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/12/testing-crud-operations-with-nhibernate/"  data-text="Testing CRUD Operations With NHibernate" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/12/testing-crud-operations-with-nhibernate/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/12/testing-crud-operations-with-nhibernate/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/12/testing-crud-operations-with-nhibernate/feed/</wfw:commentRss> <slash:comments>13</slash:comments> </item> <item><title>Unit Testing An NHibernate Application</title><link>http://davybrion.com/blog/2009/12/unit-testing-an-nhibernate-application/</link> <comments>http://davybrion.com/blog/2009/12/unit-testing-an-nhibernate-application/#comments</comments> <pubDate>Sun, 06 Dec 2009 19:21:13 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[testing]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2008</guid> <description><![CDATA[Grant Palin recently asked me for an in-depth article on TDD’ing an NHibernate application. While this post won’t be very in-depth, it might be helpful already.&#160; There are basically two approaches that i’ve seen used with good results, though there are obviously more approaches that you can use.&#160; I’m going to limit the scope of [...]]]></description> <content:encoded><![CDATA[<p></p><p></p><p><a
href="http://grantpalin.com/blog/" target="_blank">Grant Palin</a> recently <a
href="http://davybrion.com/blog/2009/11/400-posts/#comment-23070" target="_blank">asked me</a> for an in-depth article on TDD’ing an NHibernate application. While this post won’t be very in-depth, it might be helpful already.&#160; There are basically two approaches that i’ve seen used with good results, though there are obviously more approaches that you can use.&#160; I’m going to limit the scope of this post to the following two approaches though, and i’ll also discuss exactly what we test.</p><h5>Creating a new database for each test (or testfixture)</h5><p>This approach creates the database at the beginning of each test (or testfixture), runs the test (or tests in the fixture), and then destroys the database after the test (or testfixture) completed.&#160; The easiest way to do this is to create a base test class that all of you data access test class should inherit from.&#160; Here’s a simple example:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">NHibernateTest</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: #2b91af">Configuration</span> configuration;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: #2b91af">ISessionFactory</span> sessionFactory;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">TestFixtureSetUp</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> TestFixtureSetup()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; configuration = <span
style="color: blue">new</span> <span
style="color: #2b91af">Configuration</span>()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .Configure()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .AddAssembly(<span
style="color: #a31515">&quot;YourAssemblyName&quot;</span>);</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">new</span> <span
style="color: #2b91af">SchemaExport</span>(configuration).Create(<span
style="color: blue">false</span>, <span
style="color: blue">true</span>);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sessionFactory = configuration.BuildSessionFactory();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">TestFixtureTearDown</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> TestFixtureTearDown()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">new</span> <span
style="color: #2b91af">SchemaExport</span>(configuration).Drop(<span
style="color: blue">false</span>, <span
style="color: blue">true</span>);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: #2b91af">ISession</span> CreateTransactionalSession()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> session = sessionFactory.OpenSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.BeginTransaction();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> session;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>This class will create the database from scratch once for each TestFixture, which means that each test in the fixture will use the same database.&#160; It also destroys the database at the end of the fixture.&#160; It creates the database based on your mappings, and as you can see, you really don’t have to do a lot for this.&#160; If you want the database to be recreated and dropped for each test, then you obviously need to move the code in the TestFixtureSetup and TestFixtureTearDown methods to your regular SetUp and TearDown methods.&#160; If you go that route, i’d advise you to include empty template methods before and after the setup and teardown so you can plug in some extra code before and after these operations in your derived test classes.</p><p>The biggest benefit of this approach is that you don’t have any possibly present state in the database that can influence your tests.&#160; The downside is that you can’t rely on certain data (eg reference data) to be present and you have to recreate it whenever you need it.&#160;&#160; You can also use multiple transactions in your tests, though you are also responsible for cleaning any data that is left in the database at the end of each test.&#160; You also need to guarantee that this always happens because any data that is left by one test might influence another one.&#160;&#160; Also, if you leave data in the database, that might lead to problems when dropping the database, so you really need to be careful with this.</p><p>Another problem with this example is that there is no automatic way to push the ISession instance to your data access components.&#160; That could easily be added though, depending on how your data access components retrieve a reference to a valid ISession.</p><h5>Tests that automatically roll back their transactions</h5><p>This is the approach that we always use at work.&#160; These tests require your database to be set up in a valid manner before your tests begin.&#160; Each test uses one transaction, which is automatically rolled back at the end of the test to prevent the possibility of any test data remaining in the database.&#160;&#160; With this way of testing, it’s also possible to provide some kind of ‘known state’ in the database (eg reference data) that you can use from within your code.</p><p>Here’s the NHibernateTest class that our NHibernate test classes all inherit from:</p><div
style="font-family: consolas; background: white; color: black; font-size: 10pt"><p
style="margin: 0px">&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">abstract</span> <span
style="color: blue">class</span> <span
style="color: #2b91af">NHibernateTest</span></p><p
style="margin: 0px">&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">static</span> <span
style="color: blue">readonly</span> <span
style="color: #2b91af">ActiveSessionManager</span> activeSessionManager = <span
style="color: blue">new</span> <span
style="color: #2b91af">ActiveSessionManager</span>();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">private</span> <span
style="color: #2b91af">UnitOfWork</span> unitOfWork;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: #2b91af">ISession</span> session;</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">abstract</span> <span
style="color: #2b91af">ISessionProvider</span> GetSessionProvider();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">virtual</span> <span
style="color: #2b91af">IActiveSessionManager</span> GetActiveSessionManager()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">return</span> activeSessionManager;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">SetUp</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> SetUp()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; BeforeSetup();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">var</span> sessionManager = GetActiveSessionManager();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; unitOfWork = <span
style="color: blue">new</span> <span
style="color: #2b91af">UnitOfWork</span>(GetSessionProvider(), sessionManager);</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session = sessionManager.GetActiveSession();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; unitOfWork.CreateTransaction();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AfterSetup();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [<span
style="color: #2b91af">TearDown</span>]</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">public</span> <span
style="color: blue">void</span> TearDown()</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; BeforeTearDown();</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">if</span> (unitOfWork != <span
style="color: blue">null</span>)</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; unitOfWork.Dispose();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; unitOfWork = <span
style="color: blue">null</span>;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AfterTearDown();</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p><p
style="margin: 0px">&#160;</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> BeforeSetup() { }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> AfterSetup() { }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> BeforeTearDown() { }</p><p
style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span
style="color: blue">protected</span> <span
style="color: blue">virtual</span> <span
style="color: blue">void</span> AfterTearDown() { }</p><p
style="margin: 0px">&#160;&#160;&#160; }</p></div><p>&#160;</p><p>Now, this example uses our UnitOfWork and ActiveSessionManager classes (read <a
href="http://davybrion.com/blog/2008/06/managing-your-nhibernate-sessions/" target="_blank">this</a> if you haven’t seen those yet) to make sure that our data access components can access the current ISession instance.&#160; Each test has a valid ISession present, which has already created a transaction and we can create/modify/delete data, run our queries, modify some stuff again, run our queries again and perform our assertions, all in the same transaction.&#160; After the test is completed, the transaction is never committed (and thus, automatically rolled back) so none of that data ever remains in the database.</p><h5></h5><h5>What Exactly Do We Test?</h5><p>Well, we test everything basically.&#160; We test all of our CRUD operations (again, with a simple base class which only requires you to implement the BuildEntity, ModifyEntity and AssertEqual methods and does all of the operations and checks automatically) for each entity.&#160; That’s right, <em>for each entity.</em>&#160; The extra work that this requires really doesn’t take a lot of time and it lets us know for a fact that our mappings are valid.</p><p>We also test every custom query that we write, always using the following approach: create some test data, flush the session, perform your query and verify that the expected data has indeed been returned by the query, and also that data that shouldn’t have been returned isn’t there.</p><p>And that’s pretty much it.&#160; We mock the data layer in all of our other tests, so our CRUD and query tests are the only ones that actually use NHibernate and the database.&#160; But CRUD actions and queries are tested very extensively.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F12%2Funit-testing-an-nhibernate-application%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/12/unit-testing-an-nhibernate-application/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/12/unit-testing-an-nhibernate-application/"  data-text="Unit Testing An NHibernate Application" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/12/unit-testing-an-nhibernate-application/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/12/unit-testing-an-nhibernate-application/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/12/unit-testing-an-nhibernate-application/feed/</wfw:commentRss> <slash:comments>12</slash:comments> </item> <item><title>Why NHibernate Entities Need A Public Or Protected Parameterless Constructor</title><link>http://davybrion.com/blog/2009/10/why-nhibernate-entities-need-a-public-or-protected-parameterless-constructor/</link> <comments>http://davybrion.com/blog/2009/10/why-nhibernate-entities-need-a-public-or-protected-parameterless-constructor/#comments</comments> <pubDate>Sun, 04 Oct 2009 16:17:16 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1698</guid> <description><![CDATA[I have an older post where i discuss how you can implement a Value Object with NHibernate. In that post i mentioned the following: NHibernate allows a private default constructor for Value Objects, but for Entities you will need a default public or protected constructor as private is not sufficient. I got the following comment [...]]]></description> <content:encoded><![CDATA[<p>I have an older post where i discuss <a
href="http://davybrion.com/blog/2009/03/implementing-a-value-object-with-nhibernate">how you can implement a Value Object with NHibernate</a>.  In that post i mentioned the following:</p><blockquote>NHibernate allows a private default constructor for Value Objects, but for Entities you will need a default public or protected constructor as private is not sufficient.</blockquote><p>I got the following comment from someone:</p><blockquote> I too am trying to determine how well NHibernate lives up to the promise of persistence ignorance. I can definitely live with unnecessary private constructors, but I’m dubious about adding protected constructors just to support an ORM.At any rate, I was surprised by the sentence I quoted, because I didn’t realize there were any circumstances in which NHibernate required protected default constructors.</blockquote><p>Once again, the answer is related to the dynamic proxies that NHibernate uses.  Value Objects will never be proxied by NHibernate, so NHibernate only needs a private default constructor to create the instances.  If an entity is eligible for lazy loading however, then NHibernate will create a type which inherits from your entity (this is described in depth <a
href="http://davybrion.com/blog/2009/03/must-everything-be-virtual-with-nhibernate/">here</a> and <a
href="http://davybrion.com/blog/2009/09/must-everything-be-virtual-with-nhibernate-part-iii/">here</a>).  Which means that we really need either a public or protected constructor in entity classes that are eligible for lazy loading.  Consider the following class:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class SomeEntity
    {
        public SomeEntity(string someRequiredValue)
        {
        }
 
        private SomeEntity()
        {
        }
    }
</pre></div><p>If we try to create the following derived class:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class SomeEntityProxy : SomeEntity
    {
    }
</pre></div><p>We get the following compiler error:</p><p>Error   1   'ConsoleApplication1.SomeEntity.SomeEntity()' is inaccessible due to its protection level</p><p>It's a silly example, but it does show why entity types need at least a public or a protected default constructor and why a private one isn't sufficient.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F10%2Fwhy-nhibernate-entities-need-a-public-or-protected-parameterless-constructor%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/10/why-nhibernate-entities-need-a-public-or-protected-parameterless-constructor/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/10/why-nhibernate-entities-need-a-public-or-protected-parameterless-constructor/"  data-text="Why NHibernate Entities Need A Public Or Protected Parameterless Constructor" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/10/why-nhibernate-entities-need-a-public-or-protected-parameterless-constructor/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/10/why-nhibernate-entities-need-a-public-or-protected-parameterless-constructor/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/10/why-nhibernate-entities-need-a-public-or-protected-parameterless-constructor/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Must Everything Be Virtual With NHibernate, Part III</title><link>http://davybrion.com/blog/2009/09/must-everything-be-virtual-with-nhibernate-part-iii/</link> <comments>http://davybrion.com/blog/2009/09/must-everything-be-virtual-with-nhibernate-part-iii/#comments</comments> <pubDate>Sun, 27 Sep 2009 17:45:30 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1686</guid> <description><![CDATA[In the previous post i showed a piece of code which suffers from 2 problems and asked you guys to spot both problems. One of the problems was pointed out in the comments, but nobody mentioned the other one. Once again, this is the code example: Instead of making everything virtual, only properties that are [...]]]></description> <content:encoded><![CDATA[<p>In the <a
href="http://davybrion.com/blog/2009/09/must-everything-be-virtual-with-nhibernate-part-ii/">previous post</a> i showed a piece of code which suffers from 2 problems and asked you guys to spot both problems.  One of the problems was pointed out in the comments, but nobody mentioned the other one.</p><p>Once again, this is the code example:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2009/09/transitive_persistence411.png" rel="prettyPhoto[1686]"><img
src="http://davybrion.com/blog/wp-content/uploads/2009/09/transitive_persistence411.png" alt="transitive_persistence41" title="transitive_persistence41" width="798" height="635" class="aligncenter size-full wp-image-1687" /></a></p><p>Instead of making everything virtual, only properties that are eligible for lazy-loading have been made virtual.  Now, the line of code that is problematic is obviously the one where the DiscountPercentage of the customer backing field is accessed.  I will address using the field instead of the property later on in this post so bear with me for now.</p><p>There are 2 situations in which this code will fail badly.  The first situation is when you're dealing with a proxy of an Order.  If you have an uninitialized proxy of Order, and you call the non-virtual CreateOrderLine method then you will get a NullReferenceException because the proxy can't intercept the call to CreateOrderLine, and because it also can't intercept accessing the customer field, which will be null at that time.   This problem was correctly spotted by one of the people who left a comment.</p><p>The other problem is far worse, IMO.  Suppose you have a genuine instance of an Order object, but its reference properties haven't been loaded yet and are uninitialized proxies.  If there is no requirement for every public member of a proxy-able type to be virtual, then we can pretty much assume that the DiscountPercentage of the Customer class is also non-virtual.  Which means that with this code, we have no possible way of intercepting the call to the Customer's proxy's DiscountPercentage property.  Unfortunately, DiscountPercentage will have its default value of 0, so you won't get an exception... instead, the customer gets no discount even though its record in the database might have a discount set.</p><p>The possibility of running into one of these problems due to usage of an ORM and depending on how an object is loaded is simply unacceptable.  Some people commented on the usage of the customer backing field instead of the Customer property with a "then simply don't do that" response.  That's not an acceptable solution to this problem, it's a lame workaround at best.  There are plenty of reasons why people would use the backing field in their code instead of the property and if they run into this problem, they definitely will blame the ORM.  And rightfully so, i might add.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F09%2Fmust-everything-be-virtual-with-nhibernate-part-iii%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width=85px; height:21px;" allowTransparency="true"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/09/must-everything-be-virtual-with-nhibernate-part-iii/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/09/must-everything-be-virtual-with-nhibernate-part-iii/"  data-text="Must Everything Be Virtual With NHibernate, Part III" data-count="horizontal" data-via="davybrion">Tweet</a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/09/must-everything-be-virtual-with-nhibernate-part-iii/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/09/must-everything-be-virtual-with-nhibernate-part-iii/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/09/must-everything-be-virtual-with-nhibernate-part-iii/feed/</wfw:commentRss> <slash:comments>12</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 2/87 queries in 0.051 seconds using disk: basic
Object Caching 1652/1832 objects using disk: basic
Content Delivery Network via Amazon Web Services: CloudFront: d18sni7re4ly7f.cloudfront.net

Served from: davybrion.com @ 2012-02-07 08:19:46 -->
