Jaxor - Code Generator - Cool, crappy docs, but getting better
iBatis - SQL Mapper - Cool but lacks dynamic loading of child entities, great docs
Torque - Code Generator - Good, but a real pain to generate code, less than good docs
Hibernate - Reflection - Everyone's favorite reflection based persistence layer, great docs, great support
I started down this path of discovery last year. I started off with Hibernate which quickly left a bad smell in the air. However, since there were many people saying it was great and it actually looked great, I gave it a second and third try. I was never won over. One of the problems is the re-invention of the database query language. There is already one good one called SQL that most people use. Having to learn another one just doesn't make sense to me. Also, debugging was very difficult because of the reflective nature of Hibernate.
Unhappy with my experience with Hibernate, I sought out a new persistence layer. I happened upon Torque while researching some of the Struts committers. I built an application to test out the functionality of Torque. The fact that I actually could be productive with it (which I never achieved with Hibernate) was very positive. Although it was easier to debug because there were actual classes, actually creating those classes was painful, and including those classes in my project wasn't easy either. This left me grumbling and wishing for more.
At this point things were a muddled mess and nothing really stood out. A couple of my mentors were trying out different frameworks, but no one was really happy and Hibernate was gaining steam. Still frustrated from my previous experiences I avoided it and continued with Torque.
Then, a friend introduced me to iBatis. Easy to configure, great docs, not a code generator, but easier to debug than Hibernate and uses SQL to query the database! I started writing tests and the development was fast. If I ran into a problem the docs were there to help me out. Then, I ran into a problem that was not going to go away. iBatis does not handle nested lists of child objects. As a matter of fact, it can get to the point where it is issuing a new query to the database for every object in a list. This "feature" can quickly turn into a terrible performance hole if you don't know what you are doing. Even with this nasty little "feature" iBatis was still the persistence layer for me.
Then, I started doing something that always causes problems... I started reading. This time I picked up Martin Fowler's Patterns for Enterprise Application Architecture. I started reading about Data Mappers, Foriegn Key Mapping and other Object-Relational Structural Patterns. I was sold. My hero iBatis had been felled by a better idea. I started thinking about how I would implement these patterns into a package. Then I found Jaxor.
Jaxor doesn't have the docs of iBatis or the popularity of Hibernate, but it does have the favor of a couple of smart guys that I really respect. So, I started writing tests and bumped into a couple of problems, these were raised to the mailing list which quickly caused documentation to suddenly appear on the web site. Excellent! Docs are a little lacking, but the technology is there. Jaxor is fast and strong and easy to debug.
So, for the time being Jaxor is my persistence horse for now.
Posted by carl at December 17, 2003 11:58 AM
If I understand correctly, Ibatis can load nested list of child object. See Ibatis doc P25 (I am using the doc for 1.2.6 so the page number can be different for other versions) on "Complex Collection Properties".
I am not sure "how it can get to the point where it is issuing a new query to the database for every object in a list". For example, if we need to populate "productList" property of a category object (which has 10 products) dynamically, "SELECT * FROM product WHERE categoryId = ?" can be issued (as the current code does now) and IBatis will issue only this ONE query instead of 10 to populate 10 items.
Bill,
It has more to do with multiple levels of nesting. This thread covers exactly what I was talking about. Just to leave an example here, this problem surfaces when you query to find the products a group of customers has ordered. You have a list of customers where each has a list of orders where each has a list of products. This example is not a good representation of a real world problem, but the problem does exist.
Posted by: Carl at January 12, 2004 04:10 PM
This is the referenced thread: http://sourceforge.net/forum/forum.php?thread_id=952578&forum_id=206693
Posted by: Carl at January 12, 2004 04:18 PM
Comments