{"id":377,"date":"2009-08-24T21:36:14","date_gmt":"2009-08-24T20:36:14","guid":{"rendered":"http:\/\/blog.eweibel.net\/?p=377"},"modified":"2012-04-29T15:09:34","modified_gmt":"2012-04-29T13:09:34","slug":"nhibernate-mapping-posibilities","status":"publish","type":"post","link":"https:\/\/blog.eweibel.net\/?p=377","title":{"rendered":"NHibernate mapping possibilities"},"content":{"rendered":"<p>I prepare currently a new talk about <a href=\"http:\/\/nhforge.org\">NHibernate<\/a>. In this talk I&#8217;ll show the different mapping possibilities with NHibernate. To demonstrate the three possibilities (and a fourth one) I chose a quite simple model: I implement three classes Cat, Dog and Bird an for each one I chose a different mapping approach. For my little sample application I used NHibernate 2.1.0, NHibernate.Mapping.Attributes 2.1.0 and Fluent NHibernate 1.0.0.545.<\/p>\n<p><strong>NHibernate classic style &#8211; XML-Files<\/strong><br \/>\nFor the class Cat I chose to use the classic way to map the class.<br \/>\n[code language=&#8221;csharp&#8221;]<br \/>\npublic class Cat<br \/>\n{<br \/>\n\tprivate string id;<br \/>\n\tprivate string name;<br \/>\n\tprivate char sex;<br \/>\n\tprivate float weight;<\/p>\n<p>\tpublic virtual string Id<br \/>\n\t{<br \/>\n\t\tget { return id; }<br \/>\n\t\tset { id = value; }<br \/>\n\t}<\/p>\n<p>\tpublic virtual string Name<br \/>\n\t{<br \/>\n\t\tget { return name; }<br \/>\n\t\tset { name = value; }<br \/>\n\t}<\/p>\n<p>\tpublic virtual char Sex<br \/>\n\t{<br \/>\n\t\tget { return sex; }<br \/>\n\t\tset { sex = value; }<br \/>\n\t}<\/p>\n<p>\tpublic virtual float Weight<br \/>\n\t{<br \/>\n\t\tget { return weight; }<br \/>\n\t\tset { weight = value; }<br \/>\n\t}<br \/>\n}<br \/>\n[\/code]<br \/>\nAnd the XML-File Cat.hbm.xml looks like:<br \/>\n[code language=&#8221;xml&#8221;]<br \/>\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;<br \/>\n&lt;hibernate-mapping xmlns=&quot;urn:nhibernate-mapping-2.2&quot; namespace=&quot;NHibernateTest.Domain&quot; assembly=&quot;NHibernateTest&quot;&gt;<br \/>\n\t&lt;class name=&quot;Cat&quot; table=&quot;Cat&quot;&gt;<br \/>\n\t\t&lt;id name=&quot;Id&quot;&gt;<br \/>\n\t\t\t&lt;column name=&quot;CatId&quot; sql-type=&quot;char(32)&quot;\/&gt;<br \/>\n\t\t\t&lt;generator class=&quot;uuid.hex&quot; \/&gt;<br \/>\n\t\t&lt;\/id&gt;<br \/>\n\t\t&lt;property name=&quot;Name&quot;&gt;<br \/>\n\t\t\t&lt;column name=&quot;Name&quot; length=&quot;16&quot; not-null=&quot;true&quot; \/&gt;<br \/>\n\t\t&lt;\/property&gt;<br \/>\n\t\t&lt;property name=&quot;Sex&quot; \/&gt;<br \/>\n\t\t&lt;property name=&quot;Weight&quot; \/&gt;<br \/>\n\t&lt;\/class&gt;<br \/>\n&lt;\/hibernate-mapping&gt;<br \/>\n[\/code]<br \/>\nThis approach has different problems: You couldn&#8217;t easily refactor your POCOs, you have to adapt the hbm.xml files too. Another problem is that you write your entity twice: in C# and in XML, so there is a lot of noise. This is the entry point for code generation, but it isn&#8217;t a real solution, it is just a workaround to handle the necessary XML file correctly and to reduce errors by manual writing.<\/p>\n<p><strong>NHibernate.Mapping.Attributes<\/strong><br \/>\nFor the class Dog I prefer the <a href=\"http:\/\/sourceforge.net\/projects\/nhcontrib\/\">attributes <\/a>to map the class. In <a href=\"http:\/\/en.wikipedia.org\/wiki\/Java_Persistence_API\">JPA<\/a> it is my preferred way for simple and small projects, so I was very interested how they ported this approach to .Net.<br \/>\n[code language=&#8221;csharp&#8221;]<br \/>\n[Class(NameType = typeof(Dog))]<br \/>\npublic class Dog<br \/>\n{<br \/>\n\tprivate Guid id;<br \/>\n\tprivate string strName;<\/p>\n<p>\t[Id(0,<br \/>\n\tColumn = &quot;ID&quot;,<br \/>\n\tName = &quot;ID&quot;,<br \/>\n\tTypeType = typeof(Guid),<br \/>\n\tUnsavedValue = &quot;(00000000-0000-0000-0000-000000000000)&quot;<br \/>\n\t)]<br \/>\n\t[Generator(1, Class = &quot;guid.comb&quot;)]<br \/>\n\tpublic virtual Guid ID<br \/>\n\t{<br \/>\n\t\tget { return id; }<br \/>\n\t\tprivate set { id = value; }<br \/>\n\t}<\/p>\n<p>\t[Property(0, Column = &quot;Name&quot;,<br \/>\n\tName = &quot;Name&quot;,<br \/>\n\tTypeType = typeof(string),<br \/>\n\tLength = 50,<br \/>\n\tNotNull = false<br \/>\n\t)]<br \/>\n\tpublic virtual string Name<br \/>\n\t{<br \/>\n\t\tget { return strName; }<br \/>\n\t\tset { strName = value; }<br \/>\n\t}<br \/>\n}<br \/>\n[\/code]<br \/>\nWithout the property NameType in the Class-attribute the sample doesn&#8217;t run. Another thing which disturbs me is the noise in the code by the attributes. It isn&#8217;t a clean POCO approach, also because the needed specific using statements.<\/p>\n<p><strong>Fluent NHibernate<\/strong><br \/>\nFinally there is a <a href=\"http:\/\/fluentnhibernate.org\/\">third approach<\/a> how to map a class. To demonstrate this possibility a use the Bird class:<br \/>\n[code language=&#8221;csharp&#8221;]<br \/>\npublic class Bird<br \/>\n{<br \/>\n\tprivate Guid id;<br \/>\n\tprivate string strName;<\/p>\n<p>\tpublic virtual Guid ID<br \/>\n\t{<br \/>\n\t\tget { return id; }<br \/>\n\t\tprivate set { id = value; }<br \/>\n\t}<\/p>\n<p>\tpublic virtual string Name<br \/>\n\t{<br \/>\n\t\tget { return strName; }<br \/>\n\t\tset { strName = value; }<br \/>\n\t}<br \/>\n}<br \/>\n[\/code]<br \/>\nFor the mapping you have to use an additional class, which looks like that:<br \/>\n[code language=&#8221;csharp&#8221;]<br \/>\npublic class BirdMapping : ClassMap&lt;Bird&gt;<br \/>\n{<br \/>\n\tpublic BirdMapping()<br \/>\n\t{<br \/>\n\t\tId(x =&gt; x.ID);<br \/>\n\t\tMap(x =&gt; x.Name);<br \/>\n\t}<br \/>\n}<br \/>\n[\/code]<br \/>\nThis approach is really interesting. You separate your mapping from your entity, but the mapping is written in the same language like the entity itself. So you can profit of the refactor features of your IDE or of an additional tool like <a href=\"http:\/\/www.jetbrains.com\/resharper\/index.html\">Resharper<\/a>.<\/p>\n<p><strong>Use all together in the same project<\/strong><br \/>\nI tried to run all the three possibilities in one project and I used a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Factory_method_pattern\">factory method<\/a> to create the NHibernate configuration instance. This method looks like that:<br \/>\n[code language=&#8221;csharp&#8221;]<br \/>\npublic static Configuration CreateConfiguration()<br \/>\n{<br \/>\n\tConfiguration config = new Configuration();<br \/>\n\tconfig.Configure();<\/p>\n<p>\t\/\/ XML-Files<br \/>\n\tconfig.AddAssembly(Assembly.GetExecutingAssembly());<\/p>\n<p>\t\/\/ Attributes<br \/>\n\tHbmSerializer.Default.Validate = true; \/\/ Enable validation (optional)<br \/>\n\tHbmSerializer.Default.Serialize(System.Environment.CurrentDirectory, Assembly.GetExecutingAssembly());<br \/>\n\tconfig.AddDirectory(new DirectoryInfo(System.Environment.CurrentDirectory));<\/p>\n<p>\t\/\/ Fluent<br \/>\n\tconfig = Fluently.Configure(config).Mappings(m =&gt; m.FluentMappings.AddFromAssemblyOf&lt;Program&gt;()).BuildConfiguration();<\/p>\n<p>\treturn config;<br \/>\n}<br \/>\n[\/code]<br \/>\nIn a real world application I wouldn&#8217;t recommend a such configuration. An architect should decide which mapping approach is adequate. But this code snippet demonstrate that it is possible to use all three mapping possibilities at the same time.<\/p>\n<p><strong>The secret fourth possibility<\/strong><br \/>\nWhen I study NHibernate Fluent I saw on their wiki the possibility to use their Auto Mapping.<br \/>\n[code language=&#8221;csharp&#8221;]<br \/>\nprivate static Configuration CreateAutoConfiguration()<br \/>\n{<br \/>\n\tvar config = Fluently.Configure()<br \/>\n\t\t\t\t.Database(MsSqlConfiguration.MsSql2005.ConnectionString(@&quot;Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\Test.mdf;Integrated Security=True;User Instance=True&quot;)<br \/>\n\t\t\t\t\t\t\t.ShowSql())<br \/>\n\t\t\t\t.Mappings(m =&gt; m.AutoMappings.Add(AutoMap<br \/>\n\t\t\t\t\t\t\t\t.Assembly(Assembly.GetExecutingAssembly())<br \/>\n\t\t\t\t\t\t\t\t.Where(t =&gt; t.Namespace == &quot;NHibernateTest.Domain&quot;)))<br \/>\n\t\t\t\t.ExposeConfiguration(cfg =&gt; new SchemaExport(cfg).Create(false, true))<br \/>\n\t\t\t\t.BuildConfiguration();<\/p>\n<p>\treturn config;<br \/>\n}<br \/>\n[\/code]<br \/>\nThe other three possibilities are a little bit different: there you define the mapping for each entity, which is more or less the opposite. You map by default all your entities by convention over configuration and only the exceptions have to be declared explicitly. Note that it is even possible to generate the DB schema with the ExposeConfiguration method.<br \/>\nFor <a href=\"http:\/\/en.wikipedia.org\/wiki\/Greenfield_project\">greenfield <\/a>applications or prototypes it is a great way to map your entities, but for <a href=\"http:\/\/en.wikipedia.org\/wiki\/Brownfield_%28software_development%29\">brownfield <\/a>applications it is much harder to use. This is the case when you couldn&#8217;t discover a pattern in the database or in the entities, which you want to map. In a such scenario I would prefer one of the three other possibilities.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I prepare currently a new talk about NHibernate. In this talk I&#8217;ll show the different mapping possibilities with NHibernate. To demonstrate the three possibilities (and a fourth one) I chose a quite simple model: I implement three classes Cat, Dog and Bird an for each one I chose a different mapping approach. For my little sample application I used NHibernate 2.1.0, NHibernate.Mapping.Attributes 2.1.0 and Fluent NHibernate 1.0.0.545. NHibernate classic style &#8211; XML-Files For the class Cat I chose to use&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/blog.eweibel.net\/?p=377\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[13,14],"tags":[],"class_list":["post-377","post","type-post","status-publish","format-standard","hentry","category-net","category-software-engineering"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/plOV9-65","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":745,"url":"https:\/\/blog.eweibel.net\/?p=745","url_meta":{"origin":377,"position":0},"title":"ConfORM &ndash; Another NHibernate mapping possibility","author":"Patrick","date":"1. Sep 2010","format":false,"excerpt":"I recently hold two presentations at the .Net User Group Bern (DNUG) with Ren\u00e9 Leupold about object relational mapping in the .Net world. We showed Entity Framework 4.0 and NHibernate. My part was NHibernate. You could download the slides and samples from the DNUG website. In the two presentations I\u2026","rel":"","context":"In &quot;.NET&quot;","block_context":{"text":".NET","link":"https:\/\/blog.eweibel.net\/?cat=13"},"img":{"alt_text":"ConfOrmBigTransparent","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/ConfOrmBigTransparent_thumb.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":761,"url":"https:\/\/blog.eweibel.net\/?p=761","url_meta":{"origin":377,"position":1},"title":"NHibernate presentations at DNUG Bern","author":"Patrick","date":"2. Sep 2010","format":false,"excerpt":"I hold in August two presentations at the .Net User Group Bern together with Ren\u00e9 Leupold.\u00a0 In both presentations the topic was object relational mapping in the .Net world. So we showed Microsoft Entity Framework 4.0 and NHibernate. My part was NHibernate and Rene showed EF. In the first presentation\u2026","rel":"","context":"In &quot;.NET&quot;","block_context":{"text":".NET","link":"https:\/\/blog.eweibel.net\/?cat=13"},"img":{"alt_text":"dnugbe","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/dnugbe_thumb.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":797,"url":"https:\/\/blog.eweibel.net\/?p=797","url_meta":{"origin":377,"position":2},"title":"NHibernate day in Bologna","author":"Patrick","date":"25. Oct 2010","format":false,"excerpt":"During a whole day several speakers spoke about NHibernate and related topics. This conference was in Bologna and was very well prepared and organized. You could watch the slides and the videos of the sessions here. I joined the following sessions: Keynote Simone Chiaretta opened the conference and showed during\u2026","rel":"","context":"In &quot;.NET&quot;","block_context":{"text":".NET","link":"https:\/\/blog.eweibel.net\/?cat=13"},"img":{"alt_text":"NHDay_3","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/NHDay_3_thumb.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":160,"url":"https:\/\/blog.eweibel.net\/?p=160","url_meta":{"origin":377,"position":3},"title":"When to use stored procedures","author":"Patrick","date":"13. May 2009","format":false,"excerpt":"Recently I discussed with a colleague when to use stored procedures. As exptected it was quite a religious conversation. A few days later I found the following screencast: The Pros and Cons of Stored Procedures Based on the discussion and the screencast I tried to summarize my Pros and Cons:\u2026","rel":"","context":"In &quot;Good practices&quot;","block_context":{"text":"Good practices","link":"https:\/\/blog.eweibel.net\/?cat=5"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":459,"url":"https:\/\/blog.eweibel.net\/?p=459","url_meta":{"origin":377,"position":4},"title":"Fail Fast principle","author":"Patrick","date":"22. Sep 2009","format":false,"excerpt":"Recently I received a NullReference-Exception when I called another method from a foreign component. Fortunately I had the source code of this component and I found the following code: [code language=\"csharp\"] public class AgeValidator { public Dictionary Config { get; set; } public bool Validate(int nAge) { int nMinAge =\u2026","rel":"","context":"In &quot;Good practices&quot;","block_context":{"text":"Good practices","link":"https:\/\/blog.eweibel.net\/?cat=5"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":942,"url":"https:\/\/blog.eweibel.net\/?p=942","url_meta":{"origin":377,"position":5},"title":"Enums and inheritance in .Net","author":"Patrick","date":"9. Feb 2011","format":false,"excerpt":"In one of my current projects I had the following code (I simplified the code a bit): public string ConnectionString { get { switch(this.Importer) { case Importer.SqlServer: return \"Server=localhost;Database=Northwind\"; case Importer.SqlServerOleDb: return\"Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=Northwind\"; default: throw new NotSupportedException( string.Format(\"Importer {0} is not supported yet.\", this.Importer)); } } } After running\u2026","rel":"","context":"In &quot;.NET&quot;","block_context":{"text":".NET","link":"https:\/\/blog.eweibel.net\/?cat=13"},"img":{"alt_text":"CodeCoverage","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/CodeCoverage_thumb.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/CodeCoverage_thumb.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/CodeCoverage_thumb.png?resize=525%2C300 1.5x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts\/377","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=377"}],"version-history":[{"count":51,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts\/377\/revisions"}],"predecessor-version":[{"id":1209,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts\/377\/revisions\/1209"}],"wp:attachment":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=377"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=377"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=377"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}