The last couple of weeks I've been running around in circles, reading just about everything I been able to get my sweaty fingers on regarding NHibernate (and even alot of Hibernate docs as well)
I'm trying to create an application framework where I will be using NHibernate as the default mapper. I say default, because I really want it to be possible to shift or mapper (or dal implementation) without trouble. So...
My business objects, say User, has an interface for it's persisting and retrieving (just an example):
public interface IUser { User GetUser( Guid id ); void DeleteUser( User user ); IList GetAllUsers(); }
I then have a NHibernate implementation of this: UserMgrNH (but can make any implementation). My framework finds the correct data manager class from an xml configuration file. All this work as I want it to.
My problem lies in the LazyLoad mechanism in NHibernate. When loading an object, you do so through a Session object. When accessing a property (fx a collection of roles on my user object) it has to USE THE SAME SESSION. My problem lies in that because I've
abstracted my data access to manager classes I close the session every time. I really don't think that it's solution to just keep the session open, since it wraps an ADO connection to the database that should be closed.
All this could be solved if I just did a "manual" lazy load, ie making methods on my manager classes to load collections etc. But my next challenge is that I would like to use Paul Wilsons UI mapper to make simple administration modules in the framework.
The UI mapper ties together with any or mapper through an interface (that I've implemented to use with NHibernate). So if I bypass the lazy load in the mapper and make my own methods for retrieving fx roles for a user object, then the UI mapper cannot update
the roles since it's now out of NHibernates control.
So what does it boils down to....
I want to abstract my DAL using interfaces.
I want to use Paul Wilson's UI mapper
I would prefer to use NHibernate (but is this possible?!)
The Castle Framework actually has something for NHibernate that can do some of the stuff I'm after. But I really don't want a big framework (inside my own). Way too much configuration http://www.castleproject.org/castle/show/Facility-NHibernate
Well,, my advice is that you simply give up trying to achieve something you can not do.
In a well desigend application using an O/R mapper - the O/R mapper is being used in a LOT of situations. Unless the mapper is extremely primitive (and a toy), or the developer is using it and clueless, you will have queries, prefetch/span definitions, callbacks,
caches and all this and every such item is extremely special to the peristence layer.
So, basically, for the chance that you may change the persistence layer, you HAVE to build another one on top, with your own query langauge.
Just not worth the trouble. This goals is one of the typical goals that are just not worth achieving. With the investment you need to do to mbecome independant you can replace the mapping layer multiple times - and still save time.
That was why I want to make manager classes. As long as the business entities themself are poco then the manager classes can contain all the specifc queries (in HQL in this case). It actually works rather well. In my sample implementation I've implemented
a 3 different dals. NHibernate, Paul Wilsons OR mapper and a custom dal using stored procedures (just for the fun of it [:D])
I could of course just use Paul Wilson's or mapper now that I also want to use the UI mapper, but it falls short when you compare it to a "full" or mapper as NHibernate (don't want to turn this into a religious war, but stuff like the query language, prefetch
paths, caching and so on is kind of useful. When that is said.. I've actually made a couple of small projects using the Wilson OR mapper.)
I could of course just forget about ever making the service layer, and just let the application call the or mapper directly, but as I said I'm making a framework, and not all in my organization want to tie themself to one specific provider. Right now I'm
trying to persuade the other developers that they need to let stored procedures go [:P] which is why I really would like to use a powerful mapper (don't want them comming around saying "I could do this with my stored procedures, but I can't do it with this
stupid or mapper thingy")
Well... all opinions are welcome... Maybe I should try another mapper.
Thona: I'm actually considering looking into the EntityBroker, somehow people think that the Beta label on NHibernate (and open source altogether) is a bad thing. A main factor is also service.
On a side note... I can see that your new PowerNodes cms works out of Denmark?! How come? (I'm from DK myself, so it's just out of curiousity)
could of course just use Paul Wilson's or mapper now that I also want to use the UI mapper
You really use the UI mapper? So far I am not sure whether to stay away from it like hell (and all similar approaches) or whether it is usable at all.
My main problem is that our UI elements (PowerNodes, mostly) are really tuned to the end, and the functionality of the forms is pretty complex. I am not sure a UI mapper actually provides anything usefull there. I really like the work Paul does, but I doubt
the usefullness besides some back end forms that can look ugly.
Thona: I'm actually considering looking into the EntityBroker, somehow people think that the Beta label on NHibernate (and open source altogether) is a bad thing. A main factor is also service.
Well, depending on what features you look for the EntityBroker is propably the most powerfull solution you CAN have. It really depends on wwhat you need, particularly. We are also responsive to larger paying customers :-) Our remoting support is about the
best I can think of (PowerNodes would not be possible with another CMS - the whole Remoting story that the EntityBroker supports was done for PowerNodes and the requirements there are really extreme, with disc based cross transaction
caches, and stuff like this, simply due to the nature of the data) and we are the only one I know of now putting in a retry-logic for deadlocks (customer request, do NOT ask me whether it makes sense). The branch for the 2004.1 version goes out the next days
- right now I am redoing the whole build logic to automate it (Nant), then it branches off 2004.1 and some features have to go in that are required - from one of our larger customers as well as PowerNodes.
What we have to do is finally put the EntityBroker 2004 on our website (which is being reworked right now) and get
our marketing story better.
On a side note... I can see that your new PowerNodes cms works out of Denmark?! How come? (I'm from DK myself, so it's just out of curiousity)
Well, the story is that it is not my new PowerNodes. It is PowerNodes. It is not a THONA prodct - it is a product made from a danish company, with danish employees, working out of denmark, financed by danish investors. We
do the whole development, but are technically a contractor - albeit a special one. They are a separate entity, the project originated from them (as a matter of fact it started as a consulting job for a DAL in their old CMS, then got
bigger) and is right now looking for some venture capital to fund version 2. That is the story behind it.
You really use the UI mapper? So far I am not sure whether to stay away from it like hell (and all similar approaches) or whether it is usable at all.
...
I really like the work Paul does, but I doubt the usefullness besides some back end forms that can look ugly.
Well it doesn't have to... hmm... be ugly [:D] I've created some ui elements for it, that looks more "xp-like". I wouldn't use it for a large scale cms (or any large application that is), but besides implementing cms applications, we also do alot of small
customer specific backends. For this it would be a great time saver.
thona
Well, the story is that it is not my new PowerNodes. It is PowerNodes. It is not a THONA prodct - it is a product made from a danish company, with danish employees, working out of denmark, financed by danish investors. We
do the whole development, but are technically a contractor - albeit a special one. They are a separate entity, the project originated from them (as a matter of fact it started as a consulting job for a DAL in their old CMS, then got
bigger) and is right now looking for some venture capital to fund version 2. That is the story behind it.
Oki, just had to ask since I do alot of work with various cms applications. (also kind of a hobby) [:P]
Well it doesn't have to... hmm... be ugly I've created some ui elements for it, that looks more "xp-like".
Well, my problem is this. With our infrastructure in place- the EntityBroker as persistence layer, our Foundation as application framework, the code densitiy for most things is already REALLY low. Databinding and other controls just to most things fully
automatic ANYWAY. I just never saw the need for the UiMapper - not with the stuff we already have.
Oki, just had to ask since I do alot of work with various cms applications.
Well... It is still being worked on, and the directory will likely change tomorrow, but if you point your browser to
http://www.powernodes.com/video%20demo/FinalVideo.html you can have a look at a really different CMS application. This is a temp directory for our first demo video. If you look at it you will
see that a CMS can really be - different.
There is alot of talk about or mappers and alot of you recommend NHibernate. Isn't there anybody out there that has tried abstracting the datalayer?! I mean... I not trying to make it fly or anything. Should I try another mapper? I was thinking about testing
NPersist but I don't like that you cannot use a "normal" constructor syntax (like User u = new Users() ), you have to go through NPersist.
This is a minor thing though, and in now way a show stopper.
My requirements are not that many. A want something that can work on POCOs and I want a serious query engine!
(And oh Thona, I actually think it's refreshing to see a new angle at the whole cms thing. I've worked from enterprise stuff like Tridion, to some of the smaller danish providers. My personal favorite at the moment, and the one I use the most at my work,
is actually danish: www.sitecore.net)
In the past I've thought alot about abstracting away the O/R Mapper. However, I could never find a solution for complete abstraction that was an acceptable implementation. First, many O/R Mappers don't support POCO persistence (at least about a year ago
when I looked at several). This was a major killer since any intrusive (requires interfaces or inheritance) mapper is almost impossible to abstract completely. Second, I found evidence to suggest that some things good O/R Mappers do are pretty hard/impossible
with POCO's. This indicated to me that perhaps it was just the wrong road to go down to try and abstract away the mapper completely. I'm not sure exactly how NHibernate handles some of these things (and there very well could be elegant solutions), but some
examples might be:
Lazily loaded properties (how does the mapper know when to load the data if it is not inserting itself into the object someway? AOP has some promise but isn't fulfilled on .NET yet)
Code-access security (all of these POCO mappers must heavily use reflection on private/protected fields) implies you almost always have to grant full trust to much/whole application, which is unacceptible for certain businesses
Change tracking, how do you track exactly what has and has not changed so you only update what you have to update? And do so in an efficient manner.... The brute force method would be to store an original copy of the object then do a compare or checksum
type thing, but this is either slow or does not discover the individual fields that changed - just whether any field changed.
I'm sure there are others, but the point is that as Thona said there are a lot of complicated issues that usually require a tighter coupling of your business layer to the mapper. It may not be impossible, but I just found that it wasn't worth the trouble
to try and completely abstract everything. Instead, I focused on abstracting away pieces that were logically grouped together, in an effort to make the process of switching mappers in the future (should it ever happen) a little easier/simpler.
I agree with Thona. No point in abstracting the mapper. I too tried in the past, but with a good mapper he's right, the effort in abstraction isn't worth it.
NHibernate is the best mapper I've worked with. Not to get into a pissing contest. Just saying I don't see a need to look at other mappers if you're already using it. It's easily one of the most powerful, clean, easy mappers to use, and it's free.
rsmoke21: LazyLoads are handled by proxies in NHibernate. So your lazily loaded properties have to be virtual. Not that intrusive really. You have the choice of using fields or properties for access, so full-trust shouldn't
be that big of an issue. If you can't have it, then a few extra properties are ugly, but doable. When c#2 goes live you could even mark NHibernate as a friend assembly in your project so they aren't exposed to the rest of your code I think. The change-tracking
is done on a per-member basis with object comparisons in NHibernate. At first I thought these sorts of designs were messy, but NHibernate solves this pretty elegantly by scoping the original object cache to the ISession, so as soon as that goes out of scope,
so does that extra data. In practice this gives you all the benefits of true object comparison, without the drawback of increased memory usage, orphaned objects staying in the identity-map, etc. Really pretty simple/elegant IMO.
And that's the beauty of NHibernate IMO. It's simplicity. Sure it's powerful; there's few mappers that beat it on a feature-by-feature basis. Sure it's fast and scalable compared to XPO, DataObjects.NET, or WilsonO/RMapper. The real beauty is that with every
other mapper I've used though, I've had to learn how to do what should be simple things with the mapper, and it wasn't always easy. I've had one minor issue with NHibernate (figuring out how to do the equiv of a "TOP" statement), and I still didn't spend more
than 20 minutes researching that one. I've never had to worry about how the mapper works internally like I did with WORM's identity-map and failure to keep it in synch (that may no longer be an issue with the WORM, so don't take my word on it about the current
release), I've never had to worry about session management and wether I was working with Win or WebForms like I did with XPO. I don't have to worry about wether it will support billions of records in a table/view like I did with DataObjects.NET because it's
doing things with the schema in the background. It just works, transparently, and that's good.
macrap
Participant
870 Points
174 Posts
NHibernate and servicelayer
Apr 28, 2005 08:03 AM|LINK
Hey all
The last couple of weeks I've been running around in circles, reading just about everything I been able to get my sweaty fingers on regarding NHibernate (and even alot of Hibernate docs as well)
I'm trying to create an application framework where I will be using NHibernate as the default mapper. I say default, because I really want it to be possible to shift or mapper (or dal implementation) without trouble. So...
My business objects, say User, has an interface for it's persisting and retrieving (just an example):
I then have a NHibernate implementation of this: UserMgrNH (but can make any implementation). My framework finds the correct data manager class from an xml configuration file. All this work as I want it to.
My problem lies in the LazyLoad mechanism in NHibernate. When loading an object, you do so through a Session object. When accessing a property (fx a collection of roles on my user object) it has to USE THE SAME SESSION. My problem lies in that because I've abstracted my data access to manager classes I close the session every time. I really don't think that it's solution to just keep the session open, since it wraps an ADO connection to the database that should be closed.
All this could be solved if I just did a "manual" lazy load, ie making methods on my manager classes to load collections etc. But my next challenge is that I would like to use Paul Wilsons UI mapper to make simple administration modules in the framework. The UI mapper ties together with any or mapper through an interface (that I've implemented to use with NHibernate). So if I bypass the lazy load in the mapper and make my own methods for retrieving fx roles for a user object, then the UI mapper cannot update the roles since it's now out of NHibernates control.
So what does it boils down to....
I want to abstract my DAL using interfaces.
I want to use Paul Wilson's UI mapper
I would prefer to use NHibernate (but is this possible?!)
References
I want to achieve this (abstracted DAL):
http://www.theserverside.net/articles/showarticle.tss?id=NHibernate
More: http://www.theserverside.net/articles/showarticle.tss?id=NHibernateP2
Also here: http://www.codeproject.com/dotnet/nhibernatept1.asp
The Castle Framework actually has something for NHibernate that can do some of the stuff I'm after. But I really don't want a big framework (inside my own). Way too much configuration
http://www.castleproject.org/castle/show/Facility-NHibernate
Best regards
Rasmus
Sane Productions
- Because it's too easy being insane
www.sane.dk
macrap
Participant
870 Points
174 Posts
Re: NHibernate and servicelayer
Apr 28, 2005 11:25 AM|LINK
Oh... by the way..
Before one of you suggests the NHibernate forum... I have a thread there as well, and still no solution:
http://sourceforge.net/forum/forum.php?thread_id=1267477&forum_id=252014
[:)] Rasmus
Sane Productions
- Because it's too easy being insane
www.sane.dk
thona
Member
20 Points
2923 Posts
Re: NHibernate and servicelayer
Apr 28, 2005 11:58 AM|LINK
Well,, my advice is that you simply give up trying to achieve something you can not do.
In a well desigend application using an O/R mapper - the O/R mapper is being used in a LOT of situations. Unless the mapper is extremely primitive (and a toy), or the developer is using it and clueless, you will have queries, prefetch/span definitions, callbacks, caches and all this and every such item is extremely special to the peristence layer.
So, basically, for the chance that you may change the persistence layer, you HAVE to build another one on top, with your own query langauge.
Just not worth the trouble. This goals is one of the typical goals that are just not worth achieving. With the investment you need to do to mbecome independant you can replace the mapping layer multiple times - and still save time.
macrap
Participant
870 Points
174 Posts
Re: NHibernate and servicelayer
Apr 28, 2005 12:50 PM|LINK
That was why I want to make manager classes. As long as the business entities themself are poco then the manager classes can contain all the specifc queries (in HQL in this case). It actually works rather well. In my sample implementation I've implemented a 3 different dals. NHibernate, Paul Wilsons OR mapper and a custom dal using stored procedures (just for the fun of it [:D])
I could of course just use Paul Wilson's or mapper now that I also want to use the UI mapper, but it falls short when you compare it to a "full" or mapper as NHibernate (don't want to turn this into a religious war, but stuff like the query language, prefetch paths, caching and so on is kind of useful. When that is said.. I've actually made a couple of small projects using the Wilson OR mapper.)
I could of course just forget about ever making the service layer, and just let the application call the or mapper directly, but as I said I'm making a framework, and not all in my organization want to tie themself to one specific provider. Right now I'm trying to persuade the other developers that they need to let stored procedures go [:P] which is why I really would like to use a powerful mapper (don't want them comming around saying "I could do this with my stored procedures, but I can't do it with this stupid or mapper thingy")
Well... all opinions are welcome... Maybe I should try another mapper.
Thona: I'm actually considering looking into the EntityBroker, somehow people think that the Beta label on NHibernate (and open source altogether) is a bad thing. A main factor is also service.
On a side note... I can see that your new PowerNodes cms works out of Denmark?! How come? (I'm from DK myself, so it's just out of curiousity)
/Rasmus
Sane Productions
- Because it's too easy being insane
www.sane.dk
thona
Member
20 Points
2923 Posts
Re: NHibernate and servicelayer
Apr 28, 2005 02:31 PM|LINK
could of course just use Paul Wilson's or mapper now that I also want to use the UI mapper
You really use the UI mapper? So far I am not sure whether to stay away from it like hell (and all similar approaches) or whether it is usable at all.
My main problem is that our UI elements (PowerNodes, mostly) are really tuned to the end, and the functionality of the forms is pretty complex. I am not sure a UI mapper actually provides anything usefull there. I really like the work Paul does, but I doubt the usefullness besides some back end forms that can look ugly.
Thona: I'm actually considering looking into the EntityBroker, somehow people think that the Beta label on NHibernate (and open source altogether) is a bad thing. A main factor is also service.
Well, depending on what features you look for the EntityBroker is propably the most powerfull solution you CAN have. It really depends on wwhat you need, particularly. We are also responsive to larger paying customers :-) Our remoting support is about the best I can think of (PowerNodes would not be possible with another CMS - the whole Remoting story that the EntityBroker supports was done for PowerNodes and the requirements there are really extreme, with disc based cross transaction caches, and stuff like this, simply due to the nature of the data) and we are the only one I know of now putting in a retry-logic for deadlocks (customer request, do NOT ask me whether it makes sense). The branch for the 2004.1 version goes out the next days - right now I am redoing the whole build logic to automate it (Nant), then it branches off 2004.1 and some features have to go in that are required - from one of our larger customers as well as PowerNodes.
What we have to do is finally put the EntityBroker 2004 on our website (which is being reworked right now) and get our marketing story better.
On a side note... I can see that your new PowerNodes cms works out of Denmark?! How come? (I'm from DK myself, so it's just out of curiousity)
Well, the story is that it is not my new PowerNodes. It is PowerNodes. It is not a THONA prodct - it is a product made from a danish company, with danish employees, working out of denmark, financed by danish investors. We do the whole development, but are technically a contractor - albeit a special one. They are a separate entity, the project originated from them (as a matter of fact it started as a consulting job for a DAL in their old CMS, then got bigger) and is right now looking for some venture capital to fund version 2. That is the story behind it.
macrap
Participant
870 Points
174 Posts
Re: NHibernate and servicelayer
Apr 28, 2005 02:48 PM|LINK
Well it doesn't have to... hmm... be ugly [:D] I've created some ui elements for it, that looks more "xp-like". I wouldn't use it for a large scale cms (or any large application that is), but besides implementing cms applications, we also do alot of small customer specific backends. For this it would be a great time saver.
Oki, just had to ask since I do alot of work with various cms applications. (also kind of a hobby) [:P]
/Rasmus
Sane Productions
- Because it's too easy being insane
www.sane.dk
thona
Member
20 Points
2923 Posts
Re: NHibernate and servicelayer
Apr 28, 2005 05:16 PM|LINK
Well it doesn't have to... hmm... be ugly
I've created some ui elements for it, that looks more "xp-like".
Well, my problem is this. With our infrastructure in place- the EntityBroker as persistence layer, our Foundation as application framework, the code densitiy for most things is already REALLY low. Databinding and other controls just to most things fully automatic ANYWAY. I just never saw the need for the UiMapper - not with the stuff we already have.
Oki, just had to ask since I do alot of work with various cms applications.
Well... It is still being worked on, and the directory will likely change tomorrow, but if you point your browser to http://www.powernodes.com/video%20demo/FinalVideo.html you can have a look at a really different CMS application. This is a temp directory for our first demo video. If you look at it you will see that a CMS can really be - different.
macrap
Participant
870 Points
174 Posts
Re: NHibernate and servicelayer
Apr 29, 2005 08:37 AM|LINK
Well... Back to my original question [:D]
There is alot of talk about or mappers and alot of you recommend NHibernate. Isn't there anybody out there that has tried abstracting the datalayer?! I mean... I not trying to make it fly or anything. Should I try another mapper? I was thinking about testing NPersist but I don't like that you cannot use a "normal" constructor syntax (like User u = new Users() ), you have to go through NPersist.
This is a minor thing though, and in now way a show stopper.
My requirements are not that many. A want something that can work on POCOs and I want a serious query engine!
(And oh Thona, I actually think it's refreshing to see a new angle at the whole cms thing. I've worked from enterprise stuff like Tridion, to some of the smaller danish providers. My personal favorite at the moment, and the one I use the most at my work, is actually danish: www.sitecore.net)
/Rasmus
Sane Productions
- Because it's too easy being insane
www.sane.dk
rsmoke21
Contributor
3931 Points
792 Posts
Re: NHibernate and servicelayer
Apr 29, 2005 12:12 PM|LINK
In the past I've thought alot about abstracting away the O/R Mapper. However, I could never find a solution for complete abstraction that was an acceptable implementation. First, many O/R Mappers don't support POCO persistence (at least about a year ago when I looked at several). This was a major killer since any intrusive (requires interfaces or inheritance) mapper is almost impossible to abstract completely. Second, I found evidence to suggest that some things good O/R Mappers do are pretty hard/impossible with POCO's. This indicated to me that perhaps it was just the wrong road to go down to try and abstract away the mapper completely. I'm not sure exactly how NHibernate handles some of these things (and there very well could be elegant solutions), but some examples might be:
I'm sure there are others, but the point is that as Thona said there are a lot of complicated issues that usually require a tighter coupling of your business layer to the mapper. It may not be impossible, but I just found that it wasn't worth the trouble to try and completely abstract everything. Instead, I focused on abstracting away pieces that were logically grouped together, in an effort to make the process of switching mappers in the future (should it ever happen) a little easier/simpler.
ssmoot
Participant
1760 Points
352 Posts
Re: NHibernate and servicelayer
Apr 29, 2005 05:21 PM|LINK
NHibernate is the best mapper I've worked with. Not to get into a pissing contest. Just saying I don't see a need to look at other mappers if you're already using it. It's easily one of the most powerful, clean, easy mappers to use, and it's free.
rsmoke21: LazyLoads are handled by proxies in NHibernate. So your lazily loaded properties have to be virtual. Not that intrusive really. You have the choice of using fields or properties for access, so full-trust shouldn't be that big of an issue. If you can't have it, then a few extra properties are ugly, but doable. When c#2 goes live you could even mark NHibernate as a friend assembly in your project so they aren't exposed to the rest of your code I think. The change-tracking is done on a per-member basis with object comparisons in NHibernate. At first I thought these sorts of designs were messy, but NHibernate solves this pretty elegantly by scoping the original object cache to the ISession, so as soon as that goes out of scope, so does that extra data. In practice this gives you all the benefits of true object comparison, without the drawback of increased memory usage, orphaned objects staying in the identity-map, etc. Really pretty simple/elegant IMO.
And that's the beauty of NHibernate IMO. It's simplicity. Sure it's powerful; there's few mappers that beat it on a feature-by-feature basis. Sure it's fast and scalable compared to XPO, DataObjects.NET, or WilsonO/RMapper. The real beauty is that with every other mapper I've used though, I've had to learn how to do what should be simple things with the mapper, and it wasn't always easy. I've had one minor issue with NHibernate (figuring out how to do the equiv of a "TOP" statement), and I still didn't spend more than 20 minutes researching that one. I've never had to worry about how the mapper works internally like I did with WORM's identity-map and failure to keep it in synch (that may no longer be an issue with the WORM, so don't take my word on it about the current release), I've never had to worry about session management and wether I was working with Win or WebForms like I did with XPO. I don't have to worry about wether it will support billions of records in a table/view like I did with DataObjects.NET because it's doing things with the schema in the background. It just works, transparently, and that's good.