These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Visual Studio Project structure using NHibernate
PostPosted: Sat Dec 16, 2006 9:32 pm 
Newbie

Joined: Wed Mar 29, 2006 2:24 am
Posts: 14
I was just wondering how you guys structure your projects using NHibernate. The usual setup that i often see is to have separate projects for DAL, BLL and UI. Obviously if one is using NHibernate, you'll have your mapping files included in your BLL. I prefer to use DAO's for each business object, which contains the CRUD functionalities of a BO but of course they have to be included in the BLL. That leaves me with just the static Repository class which handles basic NHibernate methods in the DAL which is pretty unrealistic. Any help is appreciated.

_________________
http://devpinoy.org/blogs/joeycalisay


Top
 Profile  
 
 Post subject: *.hbm.xml in DAL
PostPosted: Sun Dec 17, 2006 12:43 pm 
Beginner
Beginner

Joined: Thu Apr 27, 2006 12:19 pm
Posts: 33
Location: Seattle, WA
I usually structure my projects with several layers: UI, Presentation, BLL, DAL. There's no reason to have your mapping files in your BLL, most people just do it that way because it is convenient to have the class and mapping file side by side in solution explorer. I always put my mapping files in my DAL. The one great thing about NHibernate is that there is definitely a lot less code to write for your DAL.

In the BLL I expose DAO interfaces that the DAL will implement. Each of my DAOs corresponds one to one with my BLL classes. I also have the DAL contain all of the mappings and all of the NHibernate dependencies, none of the other layers reference NHibernate. In theory this would allow me to swap out my NHibernate DAL with a regular ADO.NET DAL without touching the other layers (not that I would want to). I then use an IoC container like StructureMap or Spring.NET to inject DAO implementations into my presentation layer.

Here's how I structure my dependencies:

UI depends on presentation
Presentation depends upon BLL (Presentation uses DAOs loaded by IoC container - so no direct dependency on DAL).
BLL has no dependencies
DAL depends upon BLL (for the DAO interface definitions)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 17, 2006 9:40 pm 
Newbie

Joined: Wed Mar 29, 2006 2:24 am
Posts: 14
hey thanks mate,

almost samples i find uses the same approach, IOC style. i figured later i don't have to locate the mappings in the BLL assembly. could you give me some samples then of your DAO classes?

_________________
http://devpinoy.org/blogs/joeycalisay


Top
 Profile  
 
 Post subject: DAO sample
PostPosted: Mon Dec 18, 2006 1:22 am 
Beginner
Beginner

Joined: Thu Apr 27, 2006 12:19 pm
Posts: 33
Location: Seattle, WA
No problem, glad I could help.

I have an abstract DAO base class that implements the IBaseDao<T> interface found in the BLL.

Code:
public abstract class BaseNHibernateDao<T> : IBaseDao<T>
{
    // The NHibernate ISession
    private ISession _session;

    // The object type the DAO is dealing with
    private Type persitentType = typeof(T);

    public T GetById(int id, bool shouldLock)
    {
        return Session.Load<T>(id);
    }

    // implementations for
    // GetAll, GetByCriteria, Save, Delete, Evict, Commit, etc...
}


Then I have an interface in the BLL for each of my corresponding domain object DAOs. Like IResourceDao, IUserDao, IReviewDao, IQueueDao, whatever... Then I have a class for each of these interfaces in my DAL that inherit all of their functionality from BaseNHibernateDao<T> except for domain object specific HQL queries.

Code:
public class NHibernateQueueDao : BaseNHibernateDao<Queue>, IQueueDao
{
    public IList<Queue> findAllOpenQueues()
    {
        IQuery query = session.getNamedQuery("findAllOpenQueues");
        return query.list<Queue>();
    }

    public IList<Queue> findAllOpenQueuesForUser(User user)
    {
        IQuery query = session.getNamedQuery("findAllOpenQueuesForUser");
        query.setParameter("user", user);
        return query.list<Queue>();
    }

    // other HQL/named queries
}

[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 18, 2006 7:13 am 
Newbie

Joined: Wed Mar 29, 2006 2:24 am
Posts: 14
hey thanks again. i'm just curious about your session management for your BaseNHibernateDao class, could you include some more code on the said class, would really appreciate that.

_________________
http://devpinoy.org/blogs/joeycalisay


Top
 Profile  
 
 Post subject: SessionManager
PostPosted: Tue Dec 19, 2006 3:34 pm 
Beginner
Beginner

Joined: Thu Apr 27, 2006 12:19 pm
Posts: 33
Location: Seattle, WA
I have a class named SessionManagerBase that manages my NHibernate sessions for me. The class depends upon a custom state store implementation that works for desktop and web environments - the dependencies are kind of long... Basically I have these classes in my core library:
    ISessionManager.cs
    SessionManagerBase.cs
    WebSessionManager.cs
    DesktopDessionManager.cs
    SessionManagerFactory.cs

I ask the SessionManagerFactory for a SessionManager instance and it returns the appropriate SessionManager implementation instance for the current environment (web or desktop). The only real difference between web and desktop is the state store collection it injects into SessionManagerBase. The SessionManager is used to get a NHibernate session which is then injected into my DAOs.

Code:
public class SessionManagerBase : ISessionManager
{
        public SessionManagerBase(IStateProvider stateBag, string configFilePath)
        {
            Init(stateBag, configFilePath);
        }

        public ISession GetSession()
        {
            ISession session;

            if (_stateStore.Contains(SessionKey))
            {
                // we've already created the session for this request
                session = _stateStore.Get<ISession>(SessionKey);

                if (session == null || !session.IsOpen)
                    session = _sessionFactory.OpenSession();
            }
            else
            {
                session = _sessionFactory.OpenSession();
                _stateStore.Set(SessionKey, session);
            }

            return session;
        }

        // CloseSession, CommitTran, RollbackTran, BeginTran etc...
}

When running in a web environment I use an HttpModule to open and close NHibernate sessions and transactions. My sessions are scoped to the web request (session per request).

It may not be the best approach, but it works. The important thing is that an open session gets injected into the DAOs.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 21, 2006 10:37 am 
Newbie

Joined: Wed Mar 29, 2006 2:24 am
Posts: 14
is this patterned design patterned with the hibernate support of spring framework?

_________________
http://devpinoy.org/blogs/joeycalisay


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 21, 2006 1:29 pm 
Beginner
Beginner

Joined: Thu Apr 27, 2006 12:19 pm
Posts: 33
Location: Seattle, WA
It originally didn't use Spring or any other IoC container. It would be very easy to remove the SessionManagerFactory and replace it with Spring, which was the eventual intention.


Top
 Profile  
 
 Post subject: Re: *.hbm.xml in DAL
PostPosted: Sun Jan 14, 2007 3:46 pm 
Newbie

Joined: Tue Dec 05, 2006 2:47 pm
Posts: 2
Hi,

With regard to our dependency question. I cannot see how this is done.

1. Fine
2. Point 2. I guess you have defined your business objects here that are then persisted by the DAL. If the definition of the Business Objects are in the BL, do you reference the BL in the DAL or are the definitions in some common file accessable across all layers?

Why do you have any DAO reference in the Presentation Layer at all? I would have though that the DAO would only be exposed as high as the BL as it is the business logic that requires these objects to be persisted.

Thanks in advance for your response, this is a really interesting layering issue and I would like to get a good template in place for my current and other projects.

Incidently I use Composite Application Block for my presentaiton and IOC.


TIA


Here's how I structure my dependencies:

1. UI depends on presentation
2. Presentation depends upon BLL (Presentation uses DAOs loaded by IoC container - so no direct dependency on DAL).
3. BLL has no dependencies
4. DAL depends upon BLL (for the DAO interface definitions)[/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 14, 2007 6:55 pm 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
Sneal,

I'm using pretty much the same structure you are but I'd kill to have access to something like the NHibernate ICritera objects in my DAOs. I don't want NHibernate to leak out of by DAL but I'm not particularly keen on creating a set of wrapper classes around the NHibernate ones....

How have you implemented the GetByCriteria method on the base DAO interface? I've seen a couple using query by example, but it's a bit limited.

Any suggestions?

Cheers,

Symon.


Top
 Profile  
 
 Post subject: NHibernate dependencies - queries
PostPosted: Thu Mar 01, 2007 8:10 pm 
Beginner
Beginner

Joined: Thu Apr 27, 2006 12:19 pm
Posts: 33
Location: Seattle, WA
I generally call queries from my presentation layer which are exposed as methods on the DAL interfaces which live in the BLL. This works to separate out the dependencies so that the DAL and the presentation layer depend only on the BLL, however it feels very precedural-ish since you have to modify the interface and DAO every time you want to add a new query.

Ayende has a very cool tool NHibernate Query Generator (NQG) that generates query objects from your mapping files, but unfortunately if your looking for a clean separation NQG has a dependency upon NHibernate. The usefulness for ad-hoc queries makes it hard to pass up though.

Perhaps once we have LINQ working with NHibernate this issue will go away, but in the mean time I see no "perfect" solution to this.

I'm currently implementing a query framework for our domain model that is fluent, type safe, and which has no Hibernate dependencies - but its a lot of work and almost seems silly just to avoid a dependency when you have good tools like HQL, Criteria API, NGQ, or even SQL. Here's an example query for the query framework (note: this is in Java - C# with operator overloading would be so much more fluent).

Code:
BankQuery query = new BankQuery()
   .where(
      bank.bankName.eq("WaMu"),
      bank.id.eq(2l),
      or()
         .where(
            bank.bankName.like("Washington Mutual%"),
            bank.id.eq(3l)
         )
      )
      .orderby(bank.bankName, bank.id);


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.