Blog Stats
  • Posts - 18
  • Articles - 0
  • Comments - 26
  • Trackbacks - 76

 

Generic DAO with NHibernate

4/28/06 Update: The NHibernate codeproject.com article wins ASP.NET article of the month. Woohoo!

3/14/06 Update: See how this is used in a sample application at http://www.codeproject.com/useritems/NHibernateBestPractices.asp.

 


 

Hibernate.org has a great article on creating a generic DAO for Hibernate in Java. Below is what I use for the C# port.

 

The interface for common CRUD functionality...

 

public interface GenericDAO {

T GetById(IdDataType id, bool shouldLock);

List GetAll();

List GetByExample(T exampleInstance, string[] propertiesToExclude);

T SaveOrUpdate(T entity);

void Delete(T entity);

}

 

The generic DAO implementation...

 

public abstract class GenericNHibernateDAO : GenericDAO

{

/// Could be set using contruction injection IoC

public GenericNHibernateDAO(ISessionManager sessionManager) {

this.sessionManager = sessionManager;

}

 

public T GetById(IdDataType id, bool shouldLock) {

ISession session = GetSession();

T entity;

 

if (shouldLock) {

entity = (T) session.Load(persitentType, id, LockMode.Upgrade);

}

else {

entity = (T) session.Load(persitentType, id);

}

 

return entity;

}

 

public List GetAll() {

return GetByCriteria();

}

 

protected List GetByCriteria(params ICriterion[] criterion) {

ISession session = GetSession();

ICriteria criteria = session.CreateCriteria(persitentType);

foreach (ICriterion criterium in criterion) {

criteria.Add(criterium);

}

GenericUtils genericUtils = new GenericUtils();

return genericUtils.ConvertToGenericList(criteria.List());

}

 

public List GetByExample(T exampleInstance, string[] propertiesToExclude) {

ISession session = GetSession();

ICriteria criteria = session.CreateCriteria(persitentType);

Example example = Example.Create(exampleInstance);

 

foreach (string propertyToExclude in propertiesToExclude) {

example.ExcludeProperty(propertyToExclude);

}

 

criteria.Add(example);

 

GenericUtils genericUtils = new GenericUtils();

return genericUtils.ConvertToGenericList(criteria.List());

}

 

public T SaveOrUpdate(T entity) {

ISession session = GetSession();

session.SaveOrUpdate(entity);

 

return entity;

}

 

public void Delete(T entity) {

ISession session = GetSession();

session.Delete(entity);

}

 

private ISession GetSession() {

Check.Require(sessionManager != null, "sessionManager was not set");

return sessionManager.OpenSession();

}

 

private Type persitentType = typeof(T);

private ISessionManager sessionManager;

}

 

And for using this within your code...

 

public class ProjectDAONHibernate : GenericNHibernateDAO<Project, int> {

public ProjectDAONHibernate(ISessionManager sessionManager) : base(sessionManager) {}

}

 



Notes:

NHibernate Generics: To use generics with NHibernate, use the “NHibernate Generics” assembly available at http://www.ayende.com/projects/nhibernate-query-analyzer/generics.aspx.

SessionManager: To help with NHibernate session management, a good tool of choice is Castle Project's NHibernate facility:  http://www.castleproject.org/index.php/Facility:NHibernate.  Alternatively, a good design is explained in Chapter 8 of Hibernate In Action by Christian Bauer and Gavin King.  (They should be having a second edition coming out soon.)  The beneift of using Castle Project comes to light when used in conjunction with their Transaction factility; the Transaction facility allows you to mark which actions should be transactional via inline attributes.

Design by Contract:  You may have noticed Check.Require reference.  This is a completely optional, design-by-contract constraint using the VERY light weight framework described at http://www.codeproject.com/csharp/designbycontract.asp.

I've had wonderful success with NHibernate in the past and can continue to embrace it with C# 2.0 using generics.  The .NET community is finally starting to take notice of ORM tools like NHibernate which are helping to shave weeks, if not months, off of development.  I hope you all experience similar successes.


Feedback

# re: Generic DAO with NHibernate

Gravatar I cant get this to work. Did you leave some magic out? Pleace post some code and not just a teaser :)

3/8/2006 9:17 AM | Charlie

# re: Generic DAO with NHibernate

Gravatar I'm currently preparing a few posts to describe the whole shebang. The first should be posted on Friday. The following two should come next week. Please keep your eye out for these as I would very much like feedback. 3/8/2006 10:29 AM | Billy

# re: Generic DAO with NHibernate

Gravatar Here ya go Charlie: http://www.codeproject.com/useritems/NHibernateBestPractices.asp 3/11/2006 10:26 PM | Billy

# re: Generic DAO with NHibernate

Gravatar Dear Billy,

You article is brilliant.
However I am not use to EntitySet, EntityRef, EntityList etc. Can you add Many-to-Many mapping code in your Sample?

Many thanks,
kids 4/12/2006 6:13 PM | kids

# re: Generic DAO with NHibernate

Gravatar Ironically, I did my first many-to-many relationship with NHibernate.Generics' EntityList just today. Go to http://www.ayende.com/projects/nhibernate-query-analyzer/generics.aspx and search for the phrase "many to many" under the questions section.

The nice thing is that you don't need to implement the many-to-many declarations from both sides with NHibernate.Generics. For instance, suppose you have an addresses table. A user could have multiple addresses and an address could belong to multiple people - e.g. business address. But you'd usually only manage this many-to-many relationship from the user side. In this case, you can declare the many-to-many relationship within the user HBM and class files without having to introduce it to the address class. So far, I've been very impressed with NHibernate.Generics at www.ayende.com.

Thanks for the feedback!

Billy 4/12/2006 6:32 PM | Billy McCafferty

# re: Generic DAO with NHibernate

Gravatar Hi Billy,
Thanks for the article. It seems that the link you provided in the comments (the third comment down) is broken. Not to correct you on your own link (:p) but I believe this is the article you are referring to?

http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx

~ Lacuna 6/9/2008 5:55 AM | Lacuna

Post a comment





 

 

 

Copyright © Billy McCafferty