NHibernate Screencast - Persisting the Address Book

A few weeks ago, Evan Hoff posted a screencast on building up a domain model in a test-first manner.   We talked about it and thought it might be interesting to show how to apply persistence to this already functioning and tested domain model.

So take a look and tell me what you think!  It weighs in at 40 minutes (I tried to keep it under 30 but hey).

#1 Jose avatar
Jose
11.15.2007
2:23 PM

Hey Ben, you are the man !!that was a pretty cool screencast, i've been learning NHibernate at work because of a this new project and my boss can't wait until .NET 3.5, anyway I didn't know that NHibernate would actually crated the DDL for your objects, that is way cool.Yesterday i was trying to setup a few scenarios and manage to make NHiberanmte Insert,update, and delete and POCO (Person class) to the DB which directly maps to a ONE table "Person" table so that was pretty simpleThe problem tha I also had another POCO that Derives from Person which is "Staff" so basically the "Staff" Class has a few extra properties along with the properties for "person" class: example:Person(Firstname, LastName)Staff(Email, Title) and also the properties from Person since Staff inherits from Person.I wanted to Create 2 tables in the DB one called Person and one called Staff, and basically the "staffId" would be the same of a Person Id if there was a staff to bein the DB (does that makes sense)?So to select A staff, there needs to be a Select Statement from person table and staff table that joins on personid = staffid, same is true for updates/deletes/selectsHow can i Map The "Staff" POCO which inherits from Person, and Map that to tell NHibernate to use 2 Tables the "person" and "staff" table for Inserting, updating and deleting a "Staff" POCO ??????? HOw can i do that in NHibernamte?????????Please tell me is pretty simple to do? right?What about a Class that needs to be mapped to 3 tables? Like "SalarayEmployee" which inherits from "Staff" which inherits from "Person"AM I Crazy or what?


#2 Ben Scheirman avatar
Ben Scheirman
11.15.2007
3:27 PM

No you're not crazy :)That's a common scenario.You have inheritance in your code, but not in the database.You have a few options.You could completely isolate the tables (which means you'd have duplicate columns).This is called table per concrete class.I don't like this approach, but it's possible.you could also have 1 shared base table for the base class, and rely on a shared primary key with the common columns in the base table.So something like this:table user user_id first_name last_nametable employee user _id (same as above) salaryThis models the inheritance relationship nicely, but the problem is that now we have to do a join to get an employee, which is always slower than a single table select.This is called Table Per Subclass.To get around that you can choose to flatten your hierarchy and just have 1 massive table, but a lot of the unrelated columns will be null.you also need a "Discriminator" column to tell NH what type of record each one is.This is called Table Per Hierarchy. Do a google search on those 3 terms and you'll see what I mean.


#3 jose avatar
jose
11.15.2007
10:31 PM

I think i found my solution here: http://www.hibernate.org/hib_docs/nhibernate/html/inheritance.htmlI'll let you know if it works the way I wanted :) i agree with you joining is slower but is nice to know that is there so that we i design the DB i'll know the design can work too


#4 Connor Peterson avatar
Connor Peterson
11.15.2007
11:06 PM

Thanks for this Ben.I wasnt aware that it was so easy to generate the schema.Just out of curiousity (I know this was demo code), but isn't it kind of overkill to test the nHibernate functionality?Checking the mapping files as a sanity check seems ok, but don't you have to draw the line somewhere?Just like I wouldn't run unit tests against System.Math.Max, at some point don't you need to have a little faith in the framework?


#5 Ben avatar
Ben
11.16.2007
12:04 AM

You bring up an interesting point.I'm really not testing NHibernate here, I'm testing that I've mapped all of my properties, my primary keys and (eventually) my relationships with other entities.I usually start out this low level and then I progress into more service/repository level testing.Hopefully I can demonstrate that in a future screencast.


#6 Jose avatar
Jose
11.16.2007
5:59 PM

I have a suggestion to make it to create a screen cast to demo the scenarios and more important the xml mappings for the diferent ways to map entities to teh databasesuch astable per class hierarchy table per subclass table per concrete class


#7 Paulo Quicoli avatar
Paulo Quicoli
11.19.2007
9:34 AM

Great work !please, make codes available for downloading :)Bye !


#8 David Mohundro avatar
David Mohundro
11.29.2007
5:07 PM

I enjoyed the screencast - I've just been getting into TDD and I had used Evan's screencast as one of my starting points. I appreciate getting to see how different people work as well as how different tools (like nHibernate) are used.Thanks and I look forward to more!


#9 Richard avatar
Richard
1.11.2008
6:52 AM

Good Screencast.I am looking for more resources on how to build an nhibernate helper class that creates the sessions and manages the nhibernate configuration for the application.Also on how to add a second level cache using this class.Any pointers on where to look?