Apr 28, 2006 / Replacing O/R Mapping Framework: Is It Hard?
0 commentsThere are so many O/R mapping frameworks (O/R MF) on the market these days that it is quite hard to find the best one for your project. You can't spent a life on selection, so a week on see/try/select process is all what you have. In most cases maybe it will be enough and you will find framework with required functionality with luck. However, sometimes this will be not the case.
You've made the selection and build the first release of your product. All works fine so far. Well, you've noticed some quirks with code generation and lack of important features like aggregations support, but you can live with it so far.
Then project starts to grow. More entities, more dependencies, more features. After a year you encounter really hard problems:
- Performance on average data volumes is bad. And this is a killer problem that should be addressed ASAP.
- Your O/R MF does not support inheritance, so reducing code duplications and work with general types is quite problematic
- Code generation really lacks features, so you spending more and more time on tailoring it to feet your needs
- Some annoying bugs like absence of TEXT column type support force you to dig into O/R MF code and fix them
Suddenly you start to think that O/R MF you've selected is a real pain in the neck and it should be definitely replaced with something faster and more reliable: "Why the hell we didn't use old familiar DAO pattern? At least with DAO we are in charge of everything and with database Views and Denormalization Tables system performance will be sweet! And maybe we could generate all DAOs classes with help of Code Smith, why not?" This thought pop-ups every day while you are looking at SQL Profiler and trying to reduce SQL queries from 1000 to at least 100 for a single list. How to resolve this problem?
There are three possible solutions:
- Find new (a better one) O/R MF
- Implement DAO layer and replace your O/R MF with it
- Find a way to improve your O/R MF
And there are several critteria you should use to select the best solution:
- Minimal effort on application refactoring
- Acceptable performance
- Minimal maintenance effort
- Different databases support effort (if required)
- Development speed (how it will be affected)
Let's try to evaluate all cases. Assume that application was designed without possible data layer change in mind. Let's take a system with about 20 main entities and team of 3 developers. Each entity has at least 5 methods that use O/R MF (excluding simple CRUD operations), so about 100 of methods should be refactored. Controllers has references on O/R MF as well, since usually you have to initialize and pass UnitOfWork (Session or Context) into methods (about 3 controllers for each entity, so 90 in total). Estimates will be quite abstract anyway.
Criteria | New O/R MF | DAO | Improving O/R MF |
Application refactoring Effort | Learn - 32hrs*3 = 100hrs Code generation - 40hrs All data layer methods refactoring - 100*0.5 = 50hrs Changes in UI layer - 90*1 = 90hrs. Total: 280hrs |
Code generation - 120hrs All data layer methods refactoring - 100*2 = 200hrs Changes in UI layer - 90*1 = 90hrs. Total: 410hrs |
This is a tricky part. But in general improvements you want will be very time consuming. 2-3 man-month is a quite natural estimate. But risks are high anyway. Total: 400hrs |
Effort on Acceptable Performance | Views for lists: DB views creation - 40hrs New objects configuration - 20hrs Controllers changes - 20hrs Total: 80hrs |
Views for lists: DB views creation - 40hrs New objects configuration - 10hrs Controllers changes - 20hrs Total: 70hrs |
Views for lists: DB views creation - 40hrs New objects configuration - 20hrs Controllers changes - 10hrs Total: 70hrs |
Maintenance effort | Average | Average | Low |
Different databases support effort | 20hrs | Code generation changes - 60hrs Other - 20hrs Total: 80hrs |
20hrs |
Development speed | High. After learning period, all tasks will be easy to do | Low. New DAO methods will require hand-written SQL queries and/or Views. | High. Assuming all problems resolved during O/R MF improvements. |
Total | 380hrs + High development speed - Hard performance optimization in complex cases |
560hrs - Low development speed + Better performance in complex cases |
490hrs + High development speed - High risk - Hard performance optimization in complex cases |
Some basic observations:
- O/R MF replacement/refactoring is not a easy task and will be time consuming in any way
- Refactoring existing O/R MF is a risky way (if it is not Open Source, this is completely impossible to do)
- Any O/R MF reduces possible performance optimization ways
Conclusions:
- Stick to DAO if application will work with large data volumes (1,000,000+ records). DAO is very flexible for high-end performance tuning, but you will need great DBA.
- In most cases do not try to improve existing O/R MF, since risks are high and effort significant
- Choose new O/R MF with care, based on all your experience and knows issues with existing one.
Next time I will write about more interesting topic: How to design application to support safe data layer replacement.