The posts tagged with 'NHibernate' are listed below. You can get to each post by clicking the title in the list.
- NHQS NuGet Package
- Introducing the NHibernate QuickStart (NHQS, Part 1)
- NHQS Part 3- Session Fluency Extensions
- NHQS Part 4- Multiple Database Connectivity and Transaction Management
- NHQS Part 2- SessionFactory Creation and Containment
- Taming NHibernate Child Collection Persistence
NHQS NuGet Package
This evening I was finally able to get the NHQS library up on NuGet. As always, you can use either the NuGet package explorer or the command-line tool to grab yourself NHQS.
I'll be maintaining most of the general information about NHQS on the main NHQS page here on my site, which you can see in the navigation bar above. Hope NHQS makes your life with NHibernate a little easier!
Introducing the NHibernate QuickStart (NHQS, Part 1)
If you’ve worked with me over the past year or you’ve seen one of my alt group meetings, chances are I’ve mentioned, demonstrated, or maybe stuffed down your throat, the NHQS thingamabob. With the improvements in NHibernate following .NET 4.0 and the experiences I learned in a few projects in the previous release I’ve decided to rewrite NHQS for NHibernate 3.xx. I like the improvements in NHibernate and with those and a slightly renewed focus on my goal for NHQS I felt it might be worthwhile to introduce it on its own into the wild. This post will introduce the world to NHQS and provide a guideline for its usage.
As usual the project is only as effective as is the goal it intends to serve so let’s get that out of the way.
A lot of developers want to use NHiibernate, or Fluent NHibernate, or some flavor therein, but don’t want to learn the layers and layers of how-and-why it works just to get up and running. NHQS should mitigate this confusion and ease the transition into usage of NHibernate. A secondary goal of NHQS is to make it easy for a developer to have access to any and all persistent storage mechanisms supported by NHibernate in a fluent and domain-centric manner. At the highest level, a developer facilitating object persistence via NHQS should neither need to know nor be exposed to the underlying persistence mechanism.
To accomplish that goal we’re going to walk through the steps of setting up and using NHQS to access multiple databases via the almost-too-simple-to-be-legit fluent/generic interfaces exposed almost solely via extension methods. I’m sure I’ll get burned at the stake for failing to follow someone’s NHibernate Best Practice 101 list, so I’ll apologize up front. With that, here’s the synopsis of the blog series, which I aim to complete by the end of this week.
- Introduction (this post)
- Session Factory Creation and Containment
- Session Fluency Extensions
- Transactions and Multiple Database Support
There are a few steps one must follow to get their persistence mechanism accessible via NHQS. Here they are:
- Implement the ISessionFactoryCreator interface via a class of your own (we’ll cover this in a moment)
- Add code to the startup of the calling application (or in your TestFixtureSetup method) that calls the Create method of that class to create an NHibernate ISessionFactory object instance
- Take the resultant ISessionFactory and store it using the SessionFactoryContainer class
- Write DDD-like code to get objects from databases and perform CRUD operations via an arsenal of extension methods attached to areas of NHibernate
The second post in this series will begin the process of using NHQS in a real-world situation by simplifying the art of creating ISessionFactories and storing them in a container, so check back soon.
If you’d like to skip the blogs and look at the source, feel free, I keep the NHQS source in Github .
NHQS Part 3- Session Fluency Extensions
Though this might be the poorliest-named aspect of NHQS it is my favorite part, for it takes a huge part of the complexities associated with NHibernate and makes them simple. Dirt simple. Like, “you’re kidding, right? That couldn’t possibly work,” simple.
In part 2, the session factory containment methodology was discussed and demonstrated. During the stage of session factory containment NHQS does a wee little trick; it associates all of the domain (or if you prefer, entity ) types with the session factory responsible for performing that domain type’s CRUD responsibilities.
In other words, during containment, NHQS learns that, when asked for a Person, to hand back session factory A. When asked for an Order hand back session factory B. Whatever domain is requested, the framework should know which session factory to ask for that domain object; it should be transparent to the developer using NHQS.
Take a look again at the test fixture setup for the NHQS demonstration tests. This setup function was introduced in the previous post but has been augmented to help explain the topic in this post. The relevant addition has been highlighted for simplicity.
To further explain what’s going on, let’s walk through that highlighted section, piece by piece, and get a good understanding the steps taking place at execution time.
This first part looks in the session factory container and finds the session factory that has been set to perform CRUD operations against the SQLCE database that stores Person class instances. The return of the For method is, obviously, the instance of the ISessionFactory interface that was previously stored in the container. Note – this isn’t creating a new session factory each time, because, as pointed out in a previous post, that’s the probably single most expensive [RE: painful ] thing you can do with NHibernate. Since each session factory is created once and maintained within the session factory container, the container is just handing it back based on the type of domain object needed by the calling code.
Since the For method hands back a session factory instance, this line should be relatively self-explanatory – it creates an NHibernate ISession instance and hands it back to the calling code. Now for the good stuff, the session extension methods.
Hanging off of the session object are a few NHQS extension methods. Located within the root NHQS namespace, these methods do pretty much what their normal method equivalents do – the CRUD operations against the database. The Save method takes an instance of the domain object type represented in the generic argument and saves it to the NHibernate session and eventually, the SQLCE database.
Moving on, we need to have a unit test to make sure we stored some data. As with the Save extension method, NHQS provides a retrieval methodology that uses LINQ Expressions to get to the data in the database.
This test will, obviously, pass, as the setup routine saved some data to the database. We can also ask for the specific data we saved to make sure the test isn’t returning other data that’s been persisted at some other time. The second unit test below demonstrates this in action.
Most of the extension methods have overloaded options, too, if you want to continue to chain together operations in a fluent manner. The test below demonstrates an example of this approach in action.
Just take a look at all the work NHibernate’s doing under the hood from the debugging log generated at run-time when this unit test (and the setup) are executed. As you’ll see, NHQS makes CRUD activities a lot simpler than doing multiple methods of database logic. Obviously, it makes such processes a little more testable, too.
This post sums up probably the biggest benefit NHQS could provide most developers – easy, fluent access to their domain persistence via simple, domain-centric language and chainable methods.
The final post in this series (which may be split into two posts) will demonstrate two more important facets of NHQS – multiple-database access and the big kahuna topic in most database/ORM discussions – transaction management. We’ll peek at these two topics in the next few days and wrap up this NHQS introduction.
I hope you’ve enjoyed the series so far!
NHQS Part 4- Multiple Database Connectivity and Transaction Management
Most of the previous posts have alluded to the multiple-database goal of NHQS and some of the code has demonstrated the beginnings of a demonstration of the feature. This post will take a longer look at how NHQS can provide multiple-database support and will wrap up by demonstrating transaction management within NHQS.Multiple Database Connectivity
As has been demonstrated in the previous posts’ unit test setup methods the provision within NHQS for multiple database support relies on the idea that multiple session factories are contained automatically by NHQS, and during that containment associations are made between the session factories and the domain entities they service. Take another look at the test fixture setup, which has been modified in this post to provide the initial persistence of testing data.
In this example, recall from the first post, we’ll be working with two different domain entity projects, each of which is serviced by its own session factory. Since both session factories are being contained by NHQS, the domain language specifies where the objects are sent, and the respective session factories do the rest.
To further understand how awesome this idea is take a peek at the test project’s configuration file. Note how the first of the connection strings points to a SQLCE database, and the second connection string points to a SQL Server 2008 database. So long as NHibernate supports the RDBMS you’re targeting, NHQS can target it.
The test below completes this section of the multiple-database examination by demonstrating how data from one of the databases tied to the application – the Person SQL CE table – can be pulled and inserted into a table in another database – the Customer SQL Server table.
This unit test demonstrates how you could potentially use domain language and NHQS to perform data migrations – even when the database platform is completely different.Transaction Management
Fans of the Unit of Work pattern/concept will appreciate this section of the post. Those with extensive NHibernate experience understand the idea of managing transactions explicitly rather than just expecting implicit transactions. If you’ve ever used NHProf to profile and trace your NHibernate queries you’ll know explicit transaction usage is an area it warns about repeatedly.
Basically the rule of thumb with NHibernate is that, one should always perform the work of saving, updating, and deleting related entities to an underlying persistence mechanism, in the context of an explicit transaction. Most problems or misunderstandings about when does my data truly get saved when I use NHibernate can be mitigated by using explicit transactions. Most generic approaches yield problems when dealing with transactions, so NHQS had a goal of doing its best to allow the developer the right to manage their transactions separate to the internal workings of NHQS.
Take a look at the RealWorkWrapper method within NHQS to demonstrate the way it works. The method peeks at the NHibernate session to see if it is involved in a transaction. If not, it starts its own and does the work. If so, the method just remains within that transaction as it does its own work.
One of the NHQS CRUD methods, Save, is pictured below. These two code snippets are not to dive deep into how NHQS works (that would defeat the black-box idea in the first place, right?), but rather to demonstrate how NHQS will either use the existing transaction when it exists and if not, how it will create its own. The idea being, to keep inline with an NHibernate best practice recommendation (or to keep inline with my interpretation of it, which is open to review).
Here’s the point to that shallow dive. When a developer wants to do something in NHibernate specifically and maybe use NHQS here and there, they have the freedom of doing what they want to do in their own way and to combine NHQS by simply re-using an existing NHibernate session. This way, NHQS can be added or removed in-line with your current NHibernate implementation, without having to change a whole lot. Unit-of-work aficionados will appreciate the ability of re-using the transaction for multiple database procedures, so that CRUD operations can be grouped together to ensure validity.
Examine this unit test and how it would work (and why it would be valid).
- Verify there are no records in the table
- Add one person
- Add a second person
- Verify that two records are in the table
- Throw an exception. Since the steps are being performed in a transaction – via the DoWithTransaction call wrapping the unit of work being performed – firing the exception will cause avoidance of the transaction’s commit method being called, so…
- Verify that no records exist in the database
I hope you’ve enjoyed this brief encounter with NHQS. As was stated in the original post, it had a few clear goals. I hope NHQS makes your life easier and, if you’ve recently embarked into using NHibernate, that it makes that process a little less painful. If you have any suggestions, or have extensive experience with NHibernate and find yourself strongly objecting to how NHQS does things, please leave a comment. I’m always trying to improve not only NHQS, but my understanding of how NHibernate works.
NHQS Part 2- SessionFactory Creation and Containment
As explained in various posts all over the internet ( like this one at StackOverflow ) the ISessionFactory interface is fundamental to how NHibernate works. As the StackOverflow links points out, creating a session factory is possibly the most expensive of the things NHibernate does during execution. A frequent misstep of developers new to NHibernate is to write code that will frequently – sometimes prior to each database call for the more heinous abusers – create session factory instances. As with any technology, that which isn’t used properly will probably result in less-than-favorable outcomes. NHQS simplifies this step for the developer, as well as facades the complexity associated with session factory storage once the application using the session factory has instantiated it.Example Domains
Throughout this blog series the Visual Studio 2010 solution pictured to the left will be used. The solution consists of the NHQS framework, two domain projects, two data access projects to accommodate those domain projects, and a unit test project. To demonstrate how NHQS can connect not only to multiple database instances, but to multiple database platforms agnostically, the domain/data-access examples use 2 different databases; the People scenario will be backed by a SQL Server Compact Edition database and the Orders scenario will be backed by a SQL Server 2008 database. NHQS has support for many other database platforms so you should be covered in virtually all RDBMS situations.Session Factory Creation via a Convention
Within NHQS there exists an interface named ISessionFactoryCreator. Obviously, that’s the spot at which our investigation will begin. The interface contract is shown below. The idea behind it is quite simple – just give a developer an easy way of handing their application a session factory and let them do pretty much whatever they want to do to create it.
The implementation of the session factory creator interface isn’t too difficult. For the People domain we’re using SQLCE, so the code below set up the session factory instance for that particular data source using the SQLCE persistence configuration and fluent auto-mapping. An in-depth exploration into these topics is beyond the scope of this post; I can assure you there are far better resources out there to explain such techniques. For now, take a look at the implementation.
Now that the session factory for the People data source can be created it’ll need a place to hang out in the application’s domain. The next aspect of NHQS, session factory containment, solves this problem for developers.Session Factory Containment
One of the goals of NHQS is to provide multiple database access to a single application or web site. Inspired by the idea posited in the DAAB of “accessing multiple databases by name,” this goal was an interesting one to solve. As mentioned previously, the act of creating a session factory is an expensive one and must be done sparingly. Therefore, session factories can be thought of as things that you might want to make Singleton instances, so their storage is quite important.
Once a session factory is created it must be added to the session factory containment class. This isn’t too difficult and can be demonstrated in the unit test setup method below. When the application (in this case a unit test execution) starts up, all of the session factories used by the application should be created and added to the container.
The SessionFactoryContainer class does a little more than just contain the session factories created by each ISessionFactoryCreator implementation, too, but we’ll cover those in slightly more detail in the subsequent posts. For now, consider the multi-database goal alongside the domain centric access strategy goal. Since NHQS will be containing the session factories for you, chances are it will have the ability to do some mild interrogation of the entity domains it wraps.
Consider the code below, which modifies the test setup function slightly to accommodate a second session factory that is also created by an implementation of the ISessionFactoryCreator interface.
The next post in this series will begin to explain how, once the session factories have been created and contained, the domain-centric language can provide the CRUD operations necessary to work with the entities comprising these two domains. That’s when the power and simplicity of NHQS becomes obvious, so stay tuned!
Taming NHibernate Child Collection Persistence
I’ve been using [hacking at] NHibernate as my main ORM choice for just over a year and I’ve been exceptionally happy with the growing number of projects to augment it’s functionality, especially the Fluent NHibernate and LINQ-to-NHibernate contributions. NH isn’t exactly a simple ORM layer and does have some confusing aspects. One of these aspects – at least for me – has been that I’ve seen inconsistent behavior in the persistence of child collection properties. I think I concluded via a series of unit tests this evening for myself how to gain the typical desired outcome and I felt it was something I should share.
Take, for example, the traditional order-to-order-detail relationship. The screenshot below shows a code example of a POCO domain object organization exemplifying this sort of relationship. The Product domain object has been included for the sake of completeness for this discussion.
Following in typical NHibernate/ORM style I’ve created a series of repository interfaces and implementations to provide persistence functionality for these objects; though a discussion of those implementations is somewhat beyond the scope of this article I’m relatively certain that with a bit of ORM and TDD experience the remainder of this text should still make sense. I tend to use base classes when I’m working up my unit tests. The base class below is one that I use in this storefront project example that exposes references to local instances of those repositories. Likewise, it inherits from one of the classes provided via the S#arp architecture, the RepositoryTestsBase class.
Next is an examination of the TDD setup for this domain object hierarchy. Not too complicated an idea, this is the simplest example of a storefront possible. Products are created, then a sample order is created. To the sample order two products, with varying quantities, are added to the order.
The unit tests are also as simple as the setup. Each unit test makes sure each item was saved to the persistence layer, and each bases it’s pass/fail criterion solely on the data loaded via the method in the figure above.
Seems simple enough but when the tests are executed via TestDriven.NET the tests indicate a failure to save the order details simultaneously when the order is persisted.
Now, in the case where you’re like me and you want the children to be saved with the parent, this just won’t do. If you’re of the mindset that each object should be created on it’s own in the persistence layer, this might not be so bad. My point is, the code below should save both of the order detail records with the order, each time, no matter what.
In this case, my problem was in the way I was mapping the relationship between the Order and OrderDetail classes. I’m using Fluent NHibernate and Auto Mapping, so the changes should be minimal and made within the mapping override for my Order object. The code for my Order mapping override is below.
Once I add in the single line informing the mapping that it should cascade all changes via the Cascade.All() method call, the test passes and the order detail records are created alongside the Order.
If you’re not comfortable with the cascading delete impact this would have the option for cascading only on saves and updates could be a better choice.