The Least Common Denominator approach
I was talking with a team about their project, and doing a very minor code review. Naturally, one of the things that I checked first is the data access portion of the application.
I looked at the data access code in a sense of shock. I was on a phone call with the team, with one of them speaking and I interrupted him to say something along the lines of: “Guys, the nineties called and they want their handed rolled data access back!”
Just to give you an idea, when I am saying that the code has hand rolled data layer, I mean that it include such things as string concatenation to build queries (although I couldn’t find SQL injection, which surprised me), manual hydration of the entities, manual support for “eager loading” using SELECT N+1 queries, manual support for transactions, etc.
The reason for that, it seems, is that they wanted to find the lowest common denominator approach, so “everyone” can use it.
Sorry, ain’t going to happen. The moment that you give me something like that, I am going to drop the entire thing. I cannot work like that. The sheer amount of grunt work involved in getting anything done in such a system is a complete and total blocker. It is not the lowest common denominator, it is the least common denominator.
It is ugly, it is nasty and people should really stop writing data access layers, get on with the program and use a real OR/M. Stop stealing from your clients!
Comments
Funny, I've just had a recent similar experience. I've been asked to help with an application, and in particular with their data access layer. One of their complaints is that the application is hard to change and upgrade.
One look at hard-coded SQL strings in code...."Uh, here's a potential issue"....
One possible advantage is that I may be able to replace the entire thing with a layer of my choosing.
What do you do when you have a cots product, that is rule based very normalized and their web services don't provide the functionality that you need?
Oren - I think you miss that there's not a lot of documentation in the hands of developers that shows them the ins-and-outs of ORM tools - especially nHibernate. Every .NET developer knows how to code ADO.NET because it's been in every book about .NET development for the last decade. There is a total of one book about nHibernate. One. And in my opinion, after having just read it cover to cover, it's really a pretty terrible book. Esp if you are coming from an ADO.NET-only background.
You may not like it, but everyone (including yourself) can understand the code in a roll-your-own DA layer. Is it the best way? Of course not. But it is currently still the most accessible way to do data access for all levels of .NET developers. Combined with code-gen, it's good enough for most. The onus is really on ORM promoters (MS included with Entity Framework) to sell their case to the masses. As it stands, that isn't really happening.
Bob,
I avoid using stuff like that.
Beyond that, the question cannot be parsed without additional input
Matt,
In the last 2 decades, we have seen a LOT of hand rolled DALs.
They have proven to be maintainanance hurdles over the long run in most applications.
What you really mean is the greatest common divisor: en.wikipedia.org/.../Lowest_common_denominator
@Ayende
You missed the entire point of mattmc3's post. There is a dearth of quality docs on NHibernate. The only thing that exists are snippets of code here and there.
Awhile back you posted that you created a WinForms starter app with NHibernate in order to test something or other that had to do with that day's post.
I have been eagerly awaiting release of this app so I can review an end-to-end, best practices NHibernate app that us dummies can use it as a template.
Much respect to all your NHibernate related post as I read them all, but I just cant seem to get up to speed on the product. Heck I even purchased a copy of NHProf to use as a crutch, and I have the one single book from Manning Press mentioned by mattmc3.
I know, I'm no hot-rod like a lot of the guys on here, but you could greatly expand the NHibernate market by releasing the NHibernate for Dummies end-to-end, best practices WinFoms app you wrote.
Please?
And Thanks.
Welcome to my life every day for the last 3 years. We sell a product and support it as a "development framework", so our hands are tied if we want to maintain the interface of our crappy API.
project manager,
I know of at least four different people who are giving NHibernate courses world wide.
There are more, of course, but those are the one I personally know.
As for the NH for Desktop Apps, which is the article you are referring to, it will show up in December, if all goes well.
@Ayende
Thanks for the reply. It's a disappointment as always, but I'm used to it by now.
I guess we'll just stick with ADO.NET since it's bullet-proof and a complete no-brainer to use. I keep hearing the same about HNibernate and wish we could join the fun..
My company doesnt have any $$$ right now because of the recession to send anyone to training.
Guess we'll wait until December - or for someone else in the vast NHibernate community to release a single end-to-end, simple application (customer and orders maybe?), that shows best practices. Nothing complicated - just a single, complete, simple app - a single one.
Anyone?
@project manager
look here: http://code.google.com/p/sharp-architecture/
@chrido
Thank you very much! This article certainly provides a good jumping off point as it seems to be very detailed.
Does anyone know of a similar WinForms sample?
Tell me about it...
At my place of work we are in the process of re-writing 11 legacy apps and enterprise components and we are using a hand rolled data access / object mapping layer on all of the projects. It's a DAL nightmare that's going to be a maintenance nightmare over time. Why is this happening? It's because our very experienced and talented DBAs are skeptical of ORMs and they are defacto in charge of the application's data access strategy since they can just say: "I'm not granting anything but execution rights to stored procs." Sure, we could use NHibernate w/ procs, but I don't really see the point if that's the way it's going to be.
IMHO, the best thing the ORM community could do to help adoption is to find a way to bring DBAs on board. I've spent a fair amount of time going through DBA oriented messageboards, websites, etc... and frankly there isn't much discussion about the merits of ORM outside of things like "coders want to use something so they don't have to know SQL." They don't read or accept the discussion coming out of the developer community that things like proc only rights is not buying them any practical amount of security etc... They will only embrace ORM once it becomes a part of their community's discussion.
Ayende, I wish I could just send you a patch for this.
If your client is fully versed in object-oriented development then I agree they should be using an OR/M - not a hand-written data-access library. However, are they writing object-orientated code? Perhaps their data-access layer from the nineties reflects the fact that they are still writing procedural, data-centric code from the nineties. If this is the case, an OR/M is not necessarily going to be a good fit for them. Perhaps something like the Enterprise Library Data Access block is more appropriate.
Ok I'll bite..
Why do I need an ORM when I can build a (bespoke) completely code generated data layer that reflects how my data is used by the application ? Its scaleable, manageable, can be debugged, read by any developer and understood.
NHibernate is simply a "black hole" that data passes through. Its tiresome to manage the schema, without loading the whole project and my project I can't debug to figure whats going on, error reporting is poor. Out of the box there are many performance problems like select n+1 . Writing the DTOs is slow and labourious.
As pointed out above NHibernate is not the easiest thing to learn or find quality documentation on.
To top it all off we are seeing poor performance.
In our case it means we not only have to maintain a schema but the object model as well and make sure the two are always in sync.
We have as much time in maintenance of the object model as we would a generated DAL, I don't buy the reduced maintenance thing.
All in my humble opinion, no doubt you'll disagree but having worked with frameworks that were code generated and NHibernate I wouldn't hesitate to go code generated again.
Mark,
Experience shows that it is neither maintainable nor sustainable.
I have seen a LOT more performance issues with hand rolled code (including N+1 and calling DB in a loop).
Naysayers,
If you do so little as map properties, not even bothering with relationships, and add methods to your DAL to explicitly load related entities when they are requested, then you will gain maintainability and reliability from NHibernate without wrestling with more complicated things like collection mapping. The documentation for such is more than sufficient.
Then you can gradually incorporate things like <many-to-one and collection mapping as you see fit and as your team gains experience in such areas.
Mark, I'll give you that there is a learning curve to NHibernate, but N+1 has been very common in the various handwritten DALs I've had to support over the years.
Ayende:
I've got a 27 table select statement in our code, generated by nHibernate. It then proceeds to do select n+1 on a couple of related objects, Sorry, this is not performant.
This is not complicated stuff, its just a maintenance screen where half of the stuff pulled back is not needed.
Sure I could lazy load, but in our circumstances this doesn't solve the problem - we'll still pull all that data back eventually, just taking more round trips to get it.
Im well aware that our implementation of NHibernate (that I wasn't involved in) is far from perfect, but I can't see how its possible to control it how I want.
The generated DAL I worked on was very maintainable, any structure change meant you re-generated, done.
Feel free to email me offline if you'd like to chat further - I can explain certain scenarios where I see failings in more detail.
Mark,
I can tell you right now that you are using NH properly, if you get something like that.
NH contains several features that make things like that _easy_.
Future queries, for example, are a perfect match for this.
Can someone explain (or give a link) what is N+1? :)
Goran, here you go:
http://tinyurl.com/lds5a6
Comment preview