Showing posts with label Nhibernate. Show all posts
Showing posts with label Nhibernate. Show all posts

Saturday, November 15, 2008

NHibernate Loading of Super Class

Magic!!! Table with 10 records, but when everything is loaded, it became 30 records.

What happened here? I have a super class that is inherited by another 2 subclass and the mapping strategy use here is the table-per-hierarchy mapping. In a scenario where I have to load the superclass from the database to validate some information regardless of which subclass it is. The method always return 2 times more than the data found in the table.

Spending about an hour trying to debug and googling around to understand what when wrong here but the search was not very fruitful. I just cannot believe that NHibernate does not support such issue of loading of superclass only, without multiplying the records with each subclass that inherit the superclass.

No choice, I am back to the NHibernate document and check if I have missing out any critical config for the class elemenet on the hbm file. After reading thru the list in detail, I finally found a class element that describe (polymorphism (optional, defaults to implicit): Determines whether implicit or explicit query polymorphism is used.) something close to the problem I have. Thankfully after some testing to ensure it does not produce the problem I have, I concluded the solution to this problem is to define the superclass polymorphism element to explicit.

Thursday, November 6, 2008

NHibernate Parent and Child (One-to-Many) Cascade Option

While working on a parent and child (one-to-many) nested object recently, I encountered a problem with the child object not deleted when I tried to remove the relationship even when I set the cascade option to all. After looking around and found that Oren Eini have provided a good explanation on the different option.

To delete the children object when the relationship is removed, the all-delete-orphans option have to be used. This will removed all child objects and the children will not be an orphan (without parent).

I have to agree with him that cascade option required careful attention and can be easily overlook. It can create some bugs for you if your code are not properly tested.

Thursday, September 11, 2008

Null or Exception?

Find = Null

Load = Exception


Probably about 2-3 weeks ago, while reading the thoughtblogs, I saw a few blogs argued about what should be returned from a load method, should it be a null or an exception. The same question came to me previously and left me wondering too.


While trying to provide an answer to this question, I chance upon a very simple logic when I first started to make use of Nhibernate. In scenario, when I am trying to check if a record is unique in the persistence layer, I always get an exception thrown from the Nhibernate whenever the record is unique as no similar record is found. I do not want to catch such an exception and recover from it explicit, as this is not an exception in this scenario as I do except a null record instead of an exception.


Searching around for an answer and after reading the Nhibernate document, I realize that I actually use the wrong method for this scenario. I have been using the LOAD method which I should actually use the FIND method. The LOAD method will always throw an exception whenever no record is found. The LOAD method is design to get something that you except that it must be there. Therefore, an exception will be thrown when nothing is found.


On the other hand, the find method allows you to search for record that might not exist. In this case, expecting a null record return is a norm. So why thrown an exception? Imagine when you were building a search engine and an exception is thrown when no similar record is found. Then you need to try catch such exception. Isn’t this redundant?


So from then on, I have tried to stick to this simple logic. All load method will thrown an exception and find method will not when no record is found. Use these methods in the appropriate scenario although they may be very similar. Interestingly, the answer to the question I have is not very far away and does not need to take a genius to answer it. It probably just lies somewhere around what we have been working with.


Sometimes, is good to ponder why some of the framework is design in such a way. If they are good, reference your design and code to it. This will also give your design and code with more strength as it is a true example.

Saturday, January 26, 2008

Nhibernate many-to-one (M:1) mapping

While working on a project recently, I started to analyze all the query generated by the Nhibernate for the different mapping available. Playing with the fetching strategy and lazy loading option, I will be able to see how the different queries are form. Interestingly, I realized that the M:1 mapping does not have a lazy loading option, and decided to further investigate more on this mapping.

M:1 mapping is use for object reference, the same idea as the M:1 association in the relational model. To test and see the query generated by the Nhibernate, I decided to load a class with M:1 mapping. To my surprise, the generated query pulled about 80% of the tables found in my database. Going back to the class, the class that I am trying to load have two many-to-one mapping and the referenced class also have other M:1 mapping within the class itself and the reference traverse for about four times.

With this, I started to reflect if there are something wrong with my class design and also wondering why the M:1 mapping does not support the lazy loading option? Not too sure but probably the idea of the many-to-one mapping reference object in terms of records in the database will always be smaller than the number of records for the referencing object. But imagine if the targeted growth for the referenced object is to peak to about a million records in the database and the referencing objects is about 10 million. The penalty of loading both the referencing and referenced object will be pretty obvious without the lazy loading option.

Apart from the lazy loading option, the default fetching strategy seems to be different from what is stated in the Nhibernate document for the M:1 mapping. Without specifying any fetching strategy for the M:1 mapping, the fetching strategy use is "Join". Only when it is explicitly specific to "Select", the select strategy is use. Therefore, I urged anyone using the Nhibernate with certain performance consideration in mind should start looking at the query generated by Nhibernate.

To workaround this issue, for all M:1 mapping without much targeted growth in records, the mapping will be maintain as the performance might be minimal. For mapping with a high targeted growth and with the referenced object information seldom used, the mapping relationship should be removed and only loaded when necessary through the referenced object. However, that means the logic of what to load have to be manually managed and it will be similar to the N+1 problem found with lazy loading. Ayende Rahien have some good explanation and the workaround for this N+1 problem.