Object Relation Mappers (ORM) vs Stored Procedures

By Kenneth 'RabidDog' Clark at September 21, 2011 15:21
Filed Under: Code, Hibernate, Methodologies, nHibernate, Work, Architecture

Recently I was tasked with doing some investigations as to the best route to go. Now before you go getting all excited I am not going to be posting performance comparisons or declaring an outright winner. What I am going to point out is how to make the decision based on other factors.

 

As I was looking for feed back on the respective technologies it became very clear that this is a holy war that no one can win due to the emotional attachment to our egos and having to be right and the lack of really clear distinctions between the two.

 

First lets look at some basic best practise in writing maintainable software:

  1. Make code readable
  2. Use automated testing
  3. Use version control
  4. Ensure software is well designed
  5. Use less code
  6. Encapsulate
  7. DRY – do not repeat yourself
  8. Loose coupling
  9. Write unit tests

 

This is the essence of what I feel the articles in the reference section encapsulate. The primary reason for writing maintainable code (asides from having to maintain it) is to facilitate change. Businesses are becoming more dynamic and cannot afford to wait for months or years for the implementation of a vision they had. First to market is more important than ever with smaller businesses finding it easier to compete due to software and the internet.

 

Now the generally preferred structure of a software application is view layer, business logic layer and data layer. If designed properly one can very easily attach multiple views for different platforms to the solution without having to reengineer the business logic. The data stores can also be swapped out with relative ease or perhaps extended to include other data stores.

 

So what is a stored procedure? According to wikipedia: “A stored procedure is a subroutine available to applications accessing a relational database system. Stored procedures (sometimes called a proc, sproc, StoPro, StoredProc, or SP) are actually stored in the database data dictionary.”

 

Now the benefits claimed with using stored procedures have always been related to performance. It is a common belief that stored procedures run quicker than generated SQL. While this might be the case with an experienced writer, I have had the distinct displeasure of seeing it go horribly wrong as well. This does not mean that I have not seen it happen in code but generally it is easier to fix the code than the stored procedure due to the unit tests. When changing a stored procedure inevitably you are going to have to change code. When changing DB structure you will have to change all the procedures that use that dataset and the code that maps to it.

 

Now let us get out of the emotional stuff and start comparing apples with apples.

 

If we have a look at the the description above on how to write maintainable code let see how stored procedures match up.

 

  1. Make code readable – Well no, it is a structured query language. While it looks like bad English sometimes it can be difficult to read.
  2. Use automated testing – I haven’t seen a way to automate the testing of stored procedures
  3. Use version control – I have not seen a way to handle versioning of stored procedures with ease
  4. Ensure software is well designed – Being procedural in nature there is very little design that can happen
  5. Use less code – There are certain things you can do in code you can’t do in SQL. So you might end up having to write far more SQL to facilitate it.
  6. Encapsulate – While some might argue that the procedure is encapsulated in the database I would argue that the logic is not encapsulated where it should be.
  7. DRY – do not repeat yourself – With having to name tables and operations continually there is a great deal of replication happening
  8. Loose coupling – Can stored procedures be interchanged between database vendors? Well yes, if you haven’t used vendor specific functions. It is also tightly coupled to the database unfortunately.
  9. Write unit tests – I would if I could! Haven’t seen this in Stored procedures.

 

I am not going to run the code through the same assessment as we all know that code supports all the above. Right lets get into the next point. While stored procedures might perform better, does the saving from the performance increase compliment the additional cost of maintenance attached by using stored procedures? The next question we need to ask is this. How safe is it to have business logic reside inside the database as opposed to the code base? What the you had specific rules for the same entities in a database? You would have to replicate the initial procedure and fine tune it for each entity. Now should the shared logic change you have multiple places you need to go and change. Not good!

 

I am not going to go into data parity mismatching either as that is a seperate article all toghether! Just know that it is there.

 

Lets look at it from the other side. Yes generating SQL to query a database has a certain amount of overhead. That is the only concern that people have. Let me say that again, the only con that using code over using stored procedures has is the performance aspect. So what do we do? Well lets have a look at another definition: “"Premature optimization" is a phrase used to describe a situation where a programmer lets performance considerations affect the design of a piece of code. This can result in a design that is not as clean as it could have been or code that is incorrect, because the code is complicated by the optimization and the programmer is distracted by optimizing.”

 

Is this not what we are doing when we allow the decision to use stored procedures affect our system designs? How about we try this from now on. Lets write the application first, get it working properly (even if it is a single featureSmile) and release it. Once we identify bottle necks we begin to optimise the bottle necks. This might very well include using stored procedures! Lets get out of the dark ages folks. There is no right or wrong in this realm. There is only deliver on time or don’t. Lets deliver on time Winking smile Perfection is generally a refining process any way, expecting it on the initial iteration is absurd.

 

Just to clear up any ambiguity. This article does not serve to prove or disprove the use of SQL and stored procedures. The point of the article is to make you aware that using stored procedures needs to be handled the same as writing code, carefully, with a liberal serving of caution and most of all making sure that what you are gaining is worth what you spending to gain it. Store procedures have their place, as do ORM, procedural languages and hot dogs (in my tummy!)

 

References:

NHibernate Search

By Kenneth 'RabidDog' Clark at August 20, 2011 13:59
Filed Under: C#, nHibernate, Lucene.net

Well I had all but given up on being able to use Lucene.net in the project I am currently busy with. The root indexes where being created correctly but when ever I add a child to the root collection it was not attaching the data to the indexed document. This actually provide so frustrating that I left it and continued on other aspects of the project, hoping that something might pop out at me.

Well, by God’s grace, something did. If you take the model below:

   1: [Indexed]
   2: public class Person{
   3:     [DocumentId]
   4:     public string Id{get;set;}
   5:     [Field]
   6:     public string FirstName{get;set;}
   7:     [Field]
   8:     public string LastName{get;set;}
   9:     [IndexedEmbedded(Depth = 1, Prefix = "attr_", TargetElement = typeof(PersonAttribute))]
  10:     public IList<PersonAttribute> Attributes{get;set;}
  11: }
  12:  
  13: public class PersonAttribute{
  14:     public string Id{get;set;}
  15:     [Field]
  16:     public AttributeKey Key{get;set;}
  17:     [Field]
  18:     public string Value{get;set;}
  19: }
  20:  
  21: public enum AttributeKey{
  22:     Height,
  23:     Weight,
  24:     ShoeSize
  25: }

And then of course you add the listeners:

   1: config.SetListener(NHibernate.Event.ListenerType.PostUpdate, new FullTextIndexEventListener());
   2: config.SetListener(NHibernate.Event.ListenerType.PostInsert, new FullTextIndexEventListener());
   3: config.SetListener(NHibernate.Event.ListenerType.PostDelete, new FullTextIndexEventListener());

Everything works great for the nHibernate persistence to the Postgres data store. The root entry (Person) gets added to the data store and added to the document store but when ever I add an attribute the data store gets updated correctly but is not added to the document store. So I fought and I fought and I fought and I fought till eventually I came across a listing that someone else had in their configuration file and added it to the configuration of my application. Namely:

   1: config.SetListener(NHibernate.Event.ListenerType.PostCollectionUpdate, new FullTextIndexCollectionEventListener());
   2: config.SetListener(NHibernate.Event.ListenerType.PostCollectionRemove, new FullTextIndexCollectionEventListener());
   3: config.SetListener(NHibernate.Event.ListenerType.PostCollectionRecreate, new FullTextIndexCollectionEventListener());

And viola! On update of the child attribute list the embedded indexes were added correctly. Now this might seem obvious but the documentation on configuration is hard to find so I posted it incase someone else runs into the issue.

References:

http://stackoverflow.com/questions/1328647/lucene-net-indexes-are-not-updating-when-dealing-with-many-to-many-relationships

Technorati Tags: ,,
Windows Live Tags: NHibernate,Search,Lucene
WordPress Tags: NHibernate,Search,Lucene


I am South African. Always have been always will be. I love my country. I love my wife and two children.


I also really enjoy solving problems. I currently work as a Software Architect exploring new solutions for business problems. Having been round the block a few times I enjoy showing new developers how best to solve problems, how to find answers and how to approach solution development.


In my spare time I enjoy riding my super bike, training in Systema and horsing around with my family.


Month List

Visitors

Twitter Feed

21. May 10:15
Still can't believe that they used american actors in Invictus. Just doesn't fit!

17. May 17:12
@UnexpectedPippa only 3? "Don't touch me on my studio!"

17. May 17:12
@SaartjieJoan if you look around you might see many forks hanging out of eye sockets

17. May 17:09
@SaartjieJoan That truly is amazing HAHAHAHA!