28

What are the most common mistakes and anti-patterns NHibernate user programmers make? Please explain why those are bad practices or give link to resource for further reading.

For example:

  • One anti-pattern common for new NHibernate programmers is to use identity/native POID's instead of ORM style onces. Read more here...
Darius Kucinskas
  • 391
  • 1
  • 4
  • 9
  • 1
    You can find some of the common mistakes here: [NHProf Alerts](http://nhprof.com/Learn/Alerts) –  Aug 11 '11 at 07:42
  • 1
    Also there are some valuable posts here about [NHibernate Pitfalls](http://weblogs.asp.net/ricardoperes/archive/tags/NHibernate/default.aspx) –  Aug 11 '11 at 07:45

4 Answers4

34

My personal "frequently explained" issues:

Anti-Patterns

Messing around with detached objects (SaveOrUpdate or Merge plus some messy code) instead of using DTO's. The more complex the entities are, the messier the code is. (It also means that it works quite well with trivial entities.) Ayende also calls it the Stripper Pattern and explains the encapsulation issue.

Not understanding persistence ignorance and writing NH applications as when using explicit SQL. Symptom of that: calling Update after changing an object, wondering why changes are persisted even if Update had not been called, wondering how to avoid changes to be persisted.

Not understanding transactions and the unit of work pattern. Frequent anti-patterns: implicit transactions, session-per-operation and session-per-application. Some more reading:

Using NH events to put application logic in (eg. change tracking in insert and update triggers)

Create one class per table. Some people don't understand OOD, others don't understand relational design.

Mistakes

use of one-to-one instead of many-to-one. I tried it to explain in this answer.

Using join fetch in combination with SetMaxResult. My latest answers related to that topic:

Writing self changing entities. When an entity doesn't exactly return the value that had been set by NH, it is considered dirty and gets updated in every session. For instance: replacing the NH persistent collection in a property setter.

  IList<Address> Addresses
  {
    get { return addresses; }
    // will cause the addresses collection to be built up from scratch
    // in the database in every session, even when just reading the entity.
    set { addresses = new List<Address>(value); }
  }

  int Whatever
  {
    // will make the entity dirty after reading negative values from the db.
    // this causes unexpected updates after just reading the entity.
    get { if (whatever < 0) return 0; }
    set { whatever = value; }
  }

May be more is following.

  • 2
    +1: You should add "Not using Unit of Work pattern" and "One session per application" to your list imho. – Falcon Aug 12 '11 at 07:41
  • @Falcon: yeah probably. It's a general "not understanding transactions" problem. The unit of work is a bit covered by persistence ignorance. Although they are completely different concepts, they result in the same patterns. – Stefan Steinegger Aug 16 '11 at 10:33
5

The "Select N+1 Problem".

This is where you end up executing A select for each entity you want to manipulate (N), and a select to get the list of entities (+1), instead of a single select of all entities and their attributes.

Sean McMillan
  • 5,075
  • 25
  • 26
1
  • Too many abstractions
  • Not using Automappings with FluentNHibernate
Dynamic
  • 5,746
  • 9
  • 45
  • 73
Sly
  • 111
  • 3
  • The first point is a little vague, but in case you are referring to silly notions such hiding ISession behind a "Repository" or "DAO", I agree. – chris Jan 07 '14 at 14:54
  • 1
    The second point however is nonsense. There are good reasons why we often want to have fine grained control over the physical data model and be able to decouple that from the domain model. After all, that's the point of the "M" in "ORM". Using automappings (while useful in simple scenarios) defeats that. Besides, there is also the issue of integration legacy database schemas, for which automapping is useless. – chris Jan 07 '14 at 15:00
  • I use the inbuilt by code convention based mapping. It handles a great swath of crap I would otherwise have to repeat. However it still provides the freedom to but entity specific customisation that are layered over the mapping generated by convention. Its super helpful. – Sam Feb 03 '14 at 03:11
1

Trying to abstract it out so that you can switch to Entity Framework (or something else) at a later date.

This is much, much harder than most people who attempt it realise. There are numerous differences between the two that can trip you up in ways that can be quite subtle at times. It's also very uncommon for it to actually be needed in the end -- so much so that you can be meticulously trying to implement it for years before discovering that your approach is all wrong.

Also, it restricts you from using a whole lot of NHibernate's useful and important features such as second-level caching, interception, concurrency management, change tracking, prefetch queries and so on.

If there really were a valid need to switch between NHibernate and Entity Framework, there would be an actively developed project to support this on GitHub (perhaps something in a similar vein to CommonServiceLocator) with numerous contributors and pull requests.

jammycakes
  • 1,150
  • 1
  • 11
  • 10