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 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).
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.
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.
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!
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 :)
Written by Davy Brion, published on 2011-07-06 19:22:05
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 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.
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.
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.
Written by Davy Brion, published on 2011-04-10 17:36:55
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 curious to see if this one could fill that void.
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 NHibernate In Action, 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.
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 here. 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.
But don't let my nitpicking on the querying chapter fool you. This book is very 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 ;)
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 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 :)
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:
- Retrieve single track without joins, and access each non-reference property
- Retrieve single track with joins, and access all properties, including references
- Retrieve single track without joins, and access all properties, including references (triggers lazy-loading)
- Create and persist object graph: one artist with two albums with 13 tracks each
- 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
- Retrieve created artist from nr 4 and delete its entire graph
- Create a single track
- Retrieve single track from step 7 and update it
- Retrieve single track from step 7 and update the name of one of its referenced properties
- Retrieve single track from step 7 and change one of the reference properties so it references a different instance
- Delete the track from step 7
- Retrieve 100 tracks and access each non-reference property
- Retrieve 200 tracks and access each non-reference property
- Retrieve 100 tracks without joins and access all properties, including references (triggers lazy-loading)
- Retrieve 100 tracks with joins and access all properties, including references
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.
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.
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:
(you can click on the graph to watch it in its full size)
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:
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.
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.
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.
The following graph shows the average duration of the entire scenario in a couple of different situations:
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:
As you can see, the performance penalty of the entire scenario in each situation varies between 15% and 26%.
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:
Now the difference varies between 6% and 15%.
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 :)
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 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.
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.
First, let's take a look at transitive persistence:
The output of running that code is this:
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:
Now we can get the artist we just created with a simple call to session.Get:
And here's the output of that in the console:
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:
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:
Notice that the select statement is outputted right before we access the name of the artist, instead of immediately as in the previous example.
We've got lazy-loading covered, but what about eager loading? Well, take a look at the following code:
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:
Obviously, if we omit setting the fetchmode of the albums association we get the same output as we would get from using session.Get:
Eager fetching also works in the other direction, when fetching albums with their artist included automatically:
This results in the following output:
Finally, we'll retrieve our artist and modify some of its data:
If we then run the following code again:
We can see that the data has indeed been changed as it should:
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.
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.
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:
(as you can see from the TODO statement, this whole thing is still a work in progress)
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.
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:
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.
And this is how we initialize everything:
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 :)
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:
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:
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:
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.
Finally, we add all of the following methods to each class that included this module:
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.
Finally, I needed the following 2 helper classes to make the albums bag work correctly:
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 :)