Slashdot Mirror


NHibernate 3.0 Cookbook

RickJWagner writes "Are you a .Net developer? Do you have to persist your application objects to a database? If so, I know of a book you might be interested in, Packt Publishing's NHibernate 3.0 Cookbook. NHibernate is a port of the popular Hibernate object-relational mapper (ORM, for those who like TLAs.) An object-relational mapper is a framework that lets the developer get and retrieve application state from a database, and it does so in an efficient, non-intrusive, and flexible manner. Hibernate is the top of the line ORM implementation, yet it's easy enough to learn that even a newbie will find it easy to get started." Read on for the rest of Rick's review. NHibernate 3.0 Cookbook author Dentler Jason pages 328 publisher Packt Publishing rating 7/10 reviewer RickJWagner ISBN 184951304X summary The ultimate "how-to" reference for NHibernate 3.0 This book is written in Packt's 'Cookbook' style, which means it's really a series of how-to templates that guide the reader through some goal-centric activity. A 'recipe' is a formula for accomplishing something, like setting up a session for a web application, or using a profiler with NHibernate, or creating a validator class. You may not know what some of these things do-- but you will when you read the recipe! Each recipe follows a repeated pattern, with sub-sections "Getting Ready", "How to do it", "How it works", "There's More". At first glance, this can be a little deceptive for readers of technical books-- there's really no lengthy text sections that explain the basics of the tool in the early chapters of the book. You might be lulled into thinking this means there's no explanation for how things work, but that would be wrong! The truth is, there is plenty of good NHibernate theory and explanation, it's just that it's contained within the "How it Works" and "There's More" section of each instructional section, not in a chapter devoted to overview just by itself. For this reason, I'd urge bookshelf browsers to be sure to read one topic through front-to-back thoroughly, to get a feel for how the book presents theory as well as practical hands-on-the-keyboard instruction.

As far as content goes, there is a lot of useful content in this book. The author presents 70 different recipes for activites that range from the basic (i.e. your first class-to-database mappings) to the unusual (i.e. using NHibernate Spatial for solving distance-related problems.) The author offers plenty of good text in most of these, but again-- don't be upset by the placement of the high-level material. It's all there, it's just placed a little differently than what you'd find in most technical books.

The book is easy to read. The text is plain and straight to the point, and the author's writing style is quite readable. The code examples are likewise clean and well-formatted. (By the way, I'd urge you to go to Packt's site to get the source bundle if you buy the book. There's a lot of code referenced, you certainly wouldn't want to type it all by hand if you can get it handed to you.) The book runs a little over 300 pages, and most of the type is generously spaced. This is not a strong theoretical reference, but it is more than adequate as a primer for the vast majority of the tasks you'd want to accomplish with NHibernate.

So who is this book good for? I'd give it high marks for .Net developers who want to use NHibernate, regardless of experience level with the tool. I say that because there are enough use cases presented that there is almost certainly a subset of new material for almost anyone. How about Java Hibernate users? I think it's a decent book for them-- NHibernate is a very close port of the base product, so a Java user can get something out of this book, too. (For that crowd, this would obviously not be a good primary choice, but is worthwhile reading if you already have a Java go-to reference for Hibernate.) For anyone else wanting a good high-level overview of ORM use-- I'd say this book is only of marginal value. This is because the bulk of the explanatory material is presented in the context of 'how to' accomplish some particular task and isn't easily accessible without skipping from recipe to recipe.

By the way, lest you think NHibernate is only for .Net devs, I mostly ran the code samples under MonoDevelop on Ubuntu. This was my first adventure with MonoDevelop (the open source IDE for Mono, which itself is an open source, multi-platform port of .Net.) I was pleasantly surprised by the level of polish in the development environment, it really is a nice environment. Again, if you're a Java developer, I'd consider this book a decent learning supplement but would not recommend it as a primary for Hibernate proper.

You can purchase NHibernate 3.0 Cookbook from amazon.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.

9 of 72 comments (clear)

  1. Running Franticly by GWBasic · · Score: 5, Informative

    I had the misfortune of developing with NHibernate. The root of the problem was that the engineers who started the project didn't know anything about database programming and just used NHibernate as a magic persistance layer. (These guys would write foreach loops that would suck most of the database into RAM.) Ultimately, as I learned the tool, I found that it just makes data access more complicated then it needs to be. In order to use it right, you have to know the underlying database programming concepts, which are simpler and easier to learn then the NHibernate library.

    To make matters worse, when I used NHibernate, there was a bug in runtime code generation, which was very hard to track down and impossible to fix.

    My opinion: Stick with a simple ADO -> Object mapper and write queries as-needed. If you use NHibernate, stick with the basic CRUD features. Don't rely on a more complicated library to handle things like transactions, lazy-loading, and relationship mapping. Be very careful introducing relationships into the business objects, especially automatically-populated ones. And, whatever you do, if you end up working in a project where the senior engineers and/or people who started the project treat NHibernate as a "magic persistance layer," RUN!!!

    Oh, and if you work on a project that wants a "magic persistance layer," because the engineers don't get databases, investigate document databases like MongoDB, Couch, ect. The document model maps a lot better to the object-oriented way of doing things, thus it's a lot harder for programmers who don't get databases to screw them up.

    1. Re:Running Franticly by fusiongyro · · Score: 2, Interesting

      I agree completely. I'm glad you wrote this. I wish more people would take this advice to heart.

      My situation at work is identical, except with Java and regular Hibernate. My predecessors used Hibernate figuring they could ignore the database. I came in long afterwards. I've spent the last month trying to improve the situation with Hibernate, but there's only so much that can be done when your codebase assumes that all your objects are always in memory.

      Without wanting to distract too much from what comes closer to total agreement than anything I've ever experienced on Slashdot, I am, personally, rather against "document" databases. While there wouldn't have been a Hibernate mapping to screw up or relational theory to misunderstand, I think my team would have ultimately just fetched everything from it and stuffed it back in like we're doing now. Perhaps that wouldn't be as big of a mistake with CouchDB. It would be hard to determine now.

      Another thing to consider is OODBs. I'm going to be looking at db4o pretty soon because this situation is just intolerable. I had a call with Objectivity, but they wanted in the neighborhood of $80K for a 100 client installation on a 4 processor machine with 3 developer licenses, and that's way beyond our budget. Would have probably been perfect for our situation though, due to the way they wrote the code.

    2. Re:Running Franticly by mattpalmer1086 · · Score: 2, Insightful

      Well, I'm currently working on a project that uses Hibernate in Java, and it's really quite hideous. I speak as someone who designed an object-relational mapping system ten years ago. Hibernate is much more powerful than anything I ever hoped to do - and it still sucks. We're talking about an application with 2 core classes, with a one-to-many relationship. Three tables in the underlying database. So it's about as simple a data model as you can get.

      To get it to perform, we're having to manually add indexes to the database instead of relying on hibernates automatic index generation. We're having to specify access patterns in queries and annotations. We have queries with sub-selects, which hibernate just doesn't do well. We have the need to return dynamically generated values along with the objects, which is not obvious with Hibernate, but easy in SQL. We have a mixture of HQL (Hibernate Query Language), JP-QL (Java Persistence Query Language), annotations in the code to specify mappings, and some XML mapping configuration.

      It's all so bl**dy complicated, it's not obvious what works well and what doesn't, and what to do about it if it doesn't work well. So we're fighting this thing all the way, and increasingly dropping back down to SQL, which is mature and well understood.

      The thing I've learned about Java development and developers is they are in love with interfaces, abstraction and frameworks. And its very nice to have standard ways of doing things, and pluggable interfaces, and modularity, and all that goodness.

      In many ways, this code has all the standardisation and modularity that I've been pushing as good things for years. But I guess you can have too much of a good thing. Sometimes, it really is better just to write a simpler thing yourself, instead of wrestling with ridiculously powerful APIs which are trying to satisfy everyone, and yet somehow end up never quite doing the "obvious" thing you happen to want to do.

    3. Re:Running Franticly by WarwickRyan · · Score: 2, Informative

      What the ORM gives you (in addition to the obvious) is the power to make large scale changes to your persistance infrastructure quickly and easily.

      Take caching as an example. Every time you touch the database, you pay a relatively high cost. If the data you're accessing doesn't have complex sorting or querying, then you can dramatically improve performance by caching in the webserver's memory. If your db is on the network, then the cost is even higher. Guess what? With an ORM such as nHibernate, you can have this data cached, with just a runtime setting. No downtime. No code changes.

      For projects of a certain size (not tiny, but not google/facebook size) the ability to be able to tweak your data access via configuration is well worth the initial 'extra' cost of using an ORM.

      As you say though, there are too many poor developers out there who don't understand their tools. However, you can't disparage a whole technology just because a certain group of users are too stupid to be able to use it right. It's actually a good thing: inept developers / architects / 'engineers' are flagged early on when they treat an ORM as "magic persistance layer". Much better than hiding in the woodwork until it's too late get rid of them.

    4. Re:Running Franticly by Tablizer · · Score: 2, Insightful

      The root of the problem was that the engineers who started the project didn't know anything about database programming and just used NHibernate as a magic persistance layer.

      There is a growing consensus in the industry that OOP is not well-suited at direct modeling of domain (business) objects, such as employees, products, invoices, etc. I believe this is partly because OOP lacks inherent collection-oriented idioms, and would otherwise reinvent the database if it did. Further, heavy collection-orientation tends to violate "pure" encapsulation, creating a philosophical conflict.

      OOP has worked relatively well for GUI's, presentation, and OS/system calls and services though. But with these one is dealing with dozens of instances, not thousands, which may be a clue about the difference in effectiveness.

      OOP has it's place, but that place is not everywhere. Multi-paradigm programming is catching on, and it generally agrees with this observation: use the best paradigm/tool for the job; and none is best for all jobs.

    5. Re:Running Franticly by randallman · · Score: 3, Insightful

      My experience has been similar to yours. I agree with you about the issues that exist, though I don't agree with your prescription to use only the basic features. ORM can drastically reduce code complexity and still perform well if you are willing to properly learn how to use the library and understand performance trade-offs. The main problem is that most people aren't willing to put in the time and effort (as with most everything in life).

      Some tips.

      • Make sure you have a good database design to begin with.
      • Turn on logging so that you can see the SQL statements issued. Are you pulling every field from a table when all you need is one? Are you selecting from related tables that aren't needed. Not everything need be done is the most efficient manner, but consider where optimizations can and should be performed.
      • Automated tests. Test your data model to make sure it performs both properly and efficiently.

      When using ORM, you have do have to pay attention to what's happening underneath. It's a trade-off, but in the end your code is much more simple and portable. After spending time with an ORM, surprise, you learn how to use it better.

    6. Re:Running Franticly by mugnyte · · Score: 2, Informative

        Parent sounds a little like they were in over their head. Was the problem NHibernate (the implementation) or the ORM (the concept)?

        As someone who's written an ORM that handled a medium swatch of the features for the product space (metadata, state, caching, lazy-loading, transactions mgmt, SQL generation, etc). I can say that done well, ORMs greatly simplify database-backed systems for any system size over ~10 tables, or systems with less-than-solid feature requirements.

        Simply put, there is a finite set of operations one can do against an RDBMS, and if you can continue doing all of them, then the tool shouldn't matter. Hand-scribing up your own SQL and linking it to code any way you like is fine, if you like maintaining a huge pile of boring and building estimates by the number of impacted queries from a feature request.

      You have to know the tool well - it doesn't make data flow management easier, it just moves the switches and dials to a single layer. For the vast majority of cases, ORMs are amazingly helpful.

        NHibernate and it's similars serve a legit purpose, and are used successfully throughout the dev world.

        Like Inversion Of Control, Test Driven Design, Policy Injection, Design By Contract and other modern terms for not-so-modern concepts, Object-Relational Mapping is just another tool. And like all tools - there's a world of detail under a seemingly simple concept.

       

    7. Re:Running Franticly by mugnyte · · Score: 2, Insightful

        We were discussing this just today in the office. ORMs can suffer from huge impedance issues if not used correctly: Too chatty/lazy/narrow or too wide/wasteful.

        Overall, they're trying to pick a middle ground between writing plumbing per-UI need and having a one-size-fits-none model inflator. There's a lot of tricks in there (caching, lazy loading, dynamic objects, etc) but overall it's the same trade-off any system faces.

        There shouldn't be mountains of C# to wade through to get data. If so, the implementation is off. The concept, however, I a big fan of. Even when the impedance is high.

    8. Re:Running Franticly by eennaarbrak · · Score: 2, Insightful

      My predecessors used Hibernate figuring they could ignore the database

      And there is the problem. Hibernate's designers never claimed that you could ignore the database. In fact, one of the biggest strengths of Hibernate is the fact that it does not hide the database away from you - an area where some other ORM tools (like JDO) falls flat.

      ... there's only so much that can be done when your codebase assumes that all your objects are always in memory

      Hibernate does not promote this view of persistence at all. It has a clearly defined object lifecycle and state model which allows specific control over how your entities interact with the database. Seems like you are blaming Hibernate for the shortcomings of your (or your predecessor's) design.

      Hibernate, and ORM in general, gives other advantages. Like being able to do second level caching and clustering with minimal configuration. It also reduces the amount of JDBC (or SQL) code for the most mundane (but also most significant) situations like CRUD, and using a clever combination of lazy-loading and fetching strategies allows you to optimally interact with your database without writing complex lifecycle management code. It makes your application more maintainable by providing a centralized configuration, meaning that you have less work to do when your database schema changes.

      And to preempt, yes, these advantages does have a cost. Hibernate's lifecycle and state model does not suit everybody's view of how ORM is supposed to work. The trick is to understand, in your specific situation, whether the cost is off-set by the benefit or not.