Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,125 | Comments: 45,492

filter by tags archive

NHibernate and Generic Entities

time to read 3 min | 564 words

Colin Jack has brought up the question of generic entities, which is something that I consider fairly odd use case. Generics are very useful, but not in the final entity layer (they are very useful as layer super type, though).

First, let us understand what I am are talking about when I am thinking about generic entities:


The generic entity that you see is ContactInformation<TContactInfoType>, and we want to use several specialized versions of that in our application. In this case, we have contact that can be either a string or a user.

Here is an interesting tidbit, NHibernate supports this, here it the required configuration:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
	<class name="ContactInformation`1[System.String]"
		<id name="Id">
			<generator class="identity"/>
		<property name="Contact" type="System.String"/>

	<class name="ContactInformation`1[MyBlog.User]"
		<id name="Id">
			<generator class="identity"/>
		<many-to-one name="Contact" class="MyBlog.User, Blog"/>

We can even do different associations to different classes, simple column for string, FK for user.

What we can't do is to map ContactInformation<TContactInfoType>, for the very simple reason that we have no way of doing it. Consider the example above, in one case, we are using a FK, in the other, a simple column. NHibernate has no way of guessing, and since I can't really think of a good reason to want to start mapping random values to my database, I think that NHibernate is doing a good thing by insisting that you tell it about how you want this mapped.

There may be a problem with querying this with HQL, but I think this can be gotten around to with importing the class name to an alias.

Now, let us get back to the diagram below, by show of hand (well, comments), how many of you think that this is a good way to design your entities?

An entity is not a list, to which you shove random data. It has a meaning in the domain, and it has a table in which you put the data, and you want to query it, etc. It would take some pretty peculiar use case to convince me that there isn't a really simplifying factor here by simply introducing SimpleContactInformation and UserContactInformation classes, which would simple derived from the generic class with the appropriate parameters. The ability to use generics is nice to cut duplicate code, but it also obstruct the clarity of the code, so I see this as significant added value.

In short, it is possible, but don't do it.



Thanks for the tidbit!

Whilst generics aren't something I'd put throughout the domain layer there are times that I would do it, for instance (and these are probably the only 2 times that I would have done this):

  • A generic Range value object (public class Range where T : IComaprable{})... robably mapped as a component in NHibernate.

  • And a genric TemporalProperty association object (see http://martinfowler.com/eaaDev/TemporalProperty.html) where I want to hide the fact from the consumer that I am utilising a collection internally)

So in response to your request for a show of hands... I'll put one hand up and the other one down :-)

Sean Chambers

I would personally think this would be handy to do, but would not do it myself.

The reason being is, by simply looking at the digram above it doesn't convey the meaning that well.

As you state it is possible to do this mapping with nhibernate which is great and I'm sure over a long enough time I could find a use for it, but unless I was sure that doing it this way would give me a huge benefit it would make me feel dirty.

Generics are very useful but I think people tend to go overboard with them trying to use them in instances where it's not warranted

Fabio Maulo

When entity-name feature will be ported, probably, will be more easy to query generic entities too

(ref to http://www.hibernate.org/hib_docs/reference/en/html/mapping.html


Another possible use of generics entities is the use of mapping (with all it implies).

I'm not secure but I think that, in the feature, we can think some solution and possible application of generics-entities, with a possible implementation, using special tuplizers (ref http://www.hibernate.org/hib_docs/reference/en/html/persistent-classes.html#persistent-classes-dynamicmodels)

Colin Jack

I agree with you about generics and I wasn't pushing for a mass adoption of generics in the domain. However as Gary says using them in the domain can sometimes be useful.

As you say having a generic contact information class is probably not what you want. However for something like a Range or another class in that mould having to create subclasses is a little bit nasty. Another example I can think of is where T is going to be one of more thanenum, though I'm not sure if we've ever met that case.

I'm all for expressing intent in my designs but we've definitely found a few cases where in order to just get something mapped we've had to create the non-generic subclasses despite the fact that we don't believe they've improved the design at all.

So in actual fact these non-generic subclasses (which in one case I believe aren't even exposed outside the domain) are just adding the to the conceptual burden of understanding the domain.

Anyway ta for the response, as always it was very useful.

Alan Buck

This is just an inquiry. I have admired your UML? diagrams and wonder what you are using to produce them. I would like to use the same tool myself.

Ayende Rahien

Visual Studio Class Diagrams

zahra karimi

have build this example and it works until the session.Save(newUser)

when an exception occures.

NHibernate.MappingException "Unknown Entry Class: User"


        Configuration cfg = new Configuration();


        ISessionFactory factory = cfg.BuildSessionFactory();

        ISession session = factory.OpenSession();

        ITransaction transaction = session.BeginTransaction();

        User newUser = new User();

        newUser.Id = "joe_cool";

        newUser.UserName = "Joseph Cool";

        newUser.Password = "abc123";

        newUser.EmailAddress = "joe (at) cool (dot) com";

        newUser.LastLogon = DateTime.Now;





using System;

public class User


private string id;

private string userName;

private string password;

private string emailAddress;

private DateTime lastLogon;

public User()



public string Id


    get { return id; }

    set { id = value; }


public string UserName


    get { return userName; }

    set { userName = value; }


public string Password


    get { return password; }

    set { password = value; }


public string EmailAddress


    get { return emailAddress; }

    set { emailAddress = value; }


public DateTime LastLogon


    get { return lastLogon; }

    set { lastLogon = value; }




<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">

<id name="Id" column="LogonId" type="String" length="20">

  <generator class="assigned" />


<property name="UserName" column="Name" type="String" length="40"/>

<property name="Password" type="String" length="20"/>

<property name="EmailAddress" type="String" length="40"/>

<property name="LastLogon" type="DateTime"/>


if anyone can assist me, it would be greatly apreciated

Ayende Rahien

The file name should be User.hbm.xml, and it should be an embedded resource

Comment preview

Comments have been closed on this topic.


  1. RavenDB 3.5 whirl wind tour: I'll have the 3+1 goodies to go, please - 3 days from now
  2. The design of RavenDB 4.0: Voron has a one track mind - 4 days from now
  3. RavenDB 3.5 whirl wind tour: Digging deep into the internals - 5 days from now
  4. The design of RavenDB 4.0: Separation of indexes and documents - 6 days from now
  5. RavenDB 3.5 whirl wind tour: Deeper insights to indexing - 7 days from now

And 10 more posts are pending...

There are posts all the way to May 30, 2016


  1. The design of RavenDB 4.0 (14):
    05 May 2016 - Physically segregating collections
  2. RavenDB 3.5 whirl wind tour (14):
    04 May 2016 - I’ll find who is taking my I/O bandwidth and they SHALL pay
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats