Object Relational Tool Comparison

This page has been created to compare Java ObjectRelationalMapping layers. This should help potential users to make an educated choice of O/R technology and to better understand the existing products.

Why only Java? There are ObjectRelationalMapping layers in other languages.

I second that. I'd like to know of and compare a list of ObjectRelationalToolComparisonDotNet for DotNet; does anyone know of any?

This is a good point that other languages should be present too. However, purely from usability perspective, this page is already overloaded with info as it is. Any refactoring ideas to make it more readable?

Unfortunately, I don't, since WardsWiki isn't really setup to do big tables like this ... Mostly, I just think that this page title should have the word "Java" in it, is all. A small gripe. -- francis

Fabrice Marguerie published an article on the criteria to consider when choosing an object-relational mapping tool, for Java or DotNet: http://madgeek.com/Articles/ORMapping/EN/mapping.htm''

There's also a vacuum (on the web, not just wiki) of comparison of PerlLanguage ORM tools - if you poke around mailing list archives and things, you'll see a lot of 1-vs-1 comparisons and people requesting a general comparison of Perl ORM and similar tools.


There is now a feature matrix provided for easier comparison. An asterisk means that there's some comments or further explanation of the item. All The comments are below the matrix in the original format, grouped by the features (Duplicate info should probably be deleted). The full descriptions of the features are right below the matrix.

Frameworks included in the comparison:

The feature matrix (Please, no tabs in the table!) Feature-Matrix in CSV: FeatureMatrixCsv

Includes Maintains Generates Supports Supports Supports Can fetch Supports Supports Requires Supports Supports Supports Supports
Requires Supports Mapping full support single mapping Supports both many collections inheritance associated optimistic Supports Provides Provides Requires clustering code sequences and mapping mapping persistence Supports
Free - Free - Persists manual RDBMS support relations Mapping supports of lazy identities Resolves as composite to many and of Strings, / Supports objects locking unit of work/ SUN JDO ODMG database without generation Requires autoincrements Supports class to multiple through persistence
Release no licence source Has mapping arbitrary SQL / between supports aggregate resolution for circular well as primary Aggregate one to one Integers, polymorphic one to one using / object level compliant compliant tables for loss of / byte runtime Query for primary ternary multiple classes to private through
Version fee available GUI classes building independence EJB support objects grouping functions of queries objects identities objects keys mappings associations Dates, etc. queries associations outer joins versioning transactions API API metadata transactions processing reflection Caching key generation associations tables one table fields accessors
  1. 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
Abra 0 0.9.6 Yes Yes No No No JDBC * No * Yes No No Yes * Yes * Yes Yes * No * No * Yes No * Yes * Yes No Yes Yes No No No Yes Yes No Yes * Yes ? No * Yes * No Yes *
BasicWebLib 0.7i Yes Yes No No Yes * ? * Yes Yes Yes No No No No Yes Yes Yes Yes Yes Yes Yes No No No No No No No No No Yes ? No ? ? ?
Castor 0.9.5 Yes Yes No Yes * No JDBC * No * Yes No No Yes * Yes ? No Yes Yes * Yes Yes No Yes Yes Yes * Yes No Yes No ? No Yes Yes * Yes * ? Yes * No No Yes
CayenneFramework 1.1 Yes Yes Yes No No JDBC * Yes * Yes Yes Yes Yes * Yes * Yes Yes Yes ? Yes * ? ? Yes No * Yes * ? No No Yes * ? ? ? ? ? ? ? ? ? ?
CocoBase 4 No No Yes Yes No JDBC * Yes * Yes ? Yes Yes ? ? Yes Yes Yes Yes Yes Yes Yes Yes * Yes Yes No No No ? No Yes Yes * ? ? ? ? ? ?
DataBind 0.4 Yes Yes No Yes Yes * JDBC * No Yes Yes No No No No Yes No No No ? ? No No No No No ? No No Yes No ? ? ? ? ? ?
EdgeXtend 2 * No No Yes No * No ODBC * Yes * Yes No * No * Yes * Yes Yes Yes Yes Yes Yes * No * Yes Yes Yes Yes Yes No * No No Yes Yes No No * Yes No ? Yes * ? ?
EnterpriseObjectsFramework ? No * No Yes No No JDBC * No * Yes No * No * Yes * Yes * Yes Yes Yes Yes * Yes ? Yes * No * Yes Yes * Yes No No Yes * ? No Yes * Yes * Yes * ? Yes * Yes ? ?
Expresso ? Yes Yes No No No JDBC * Yes * Yes Yes Yes ? ? ? Yes Yes Yes Yes ? ? ? ? ? Yes No No No No * No ? ? ? ? ? ? ? ?
FireStorm No *
FrontierSuite for J2EE & J2SE 3.1 No No Yes Yes No JDBC * Yes * Yes No Yes Yes Yes Yes Yes * Yes Yes Yes Yes Yes * Yes Yes Yes Yes No No No Yes * Yes Yes Yes Yes No Yes ? ? ?
FrontierSuite for JDO 3.0 SP1 No No Yes Yes No JDBC * Yes * Yes No No * Yes * Yes Yes Yes * Yes Yes Yes Yes Yes * Yes Yes Yes Yes Yes No No Yes * Yes Yes Yes Yes No Yes ? ? ?
Hibernate 3.0.2 Yes Yes No * Yes No JDBC * Yes * Yes Yes Yes Yes * Yes * Yes Yes * Yes * Yes Yes Yes * Yes * Yes * Yes * Yes * Yes No Yes * No * Yes * Yes * No * Yes * Yes * Yes * Yes (3) Yes Yes Yes
iBATIS DB Layer 2 Yes Yes No * Yes * Yes * JDBC * Yes * Yes Yes * Yes * Yes * No No No Yes * Yes * Yes Yes No Yes Yes No No * No * No No No No * Yes Yes * Yes * ? Yes * Yes ? Yes
Infobjects ObjectDRIVER Yes No No No Yes No ODBC * No * Yes No Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes No Yes Yes No * Yes No Yes No No Yes Yes Yes Yes ? ? ?
InterSystems Cache 5.0RC3 JDBC * Yes * Yes * ? Yes * ? ? ? Yes * Yes * ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Jakarta ObjectRelationalBridge 1 Yes Yes Yes * Yes No JDBC * Yes * Yes Yes Yes Yes * Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes * Yes Yes * Yes * No * Yes No * No * Yes * Yes * Yes Yes Yes Yes Yes
Java Ultra-Lite Persistence (JULP) 1.0.1 yes Yes Yes No Yes Yes Yes Yes Yes Yes No ? No Yes Yes * Yes ? Yes Yes Yes Yes Yes * No No No No No Yes Yes Yes ? Yes ? Yes Yes
JaxorFramework 2.2 Yes Yes No No * No JDBC * Yes * Yes Yes ? Yes * Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes * Yes * Yes * ? ? No Yes Yes No Yes * ? ? ? ? ? ?
JdoGenie 1.3.2 No * No Yes Yes No JDBC * Yes * Yes No No Yes * Yes Yes Yes * Yes Yes * Yes Yes Yes Yes Yes * Yes * Yes Yes No Yes * Yes * Yes * No Yes * Yes ? ? ? ? ?
JdoMax 1.0 Yes No No Yes No yes No Yes No Yes Yes Yes Yes Yes No Yes Yes Yes Yes Yes Yes Yes Yes Yes No No No Yes No Yes Yes Yes Yes Yes Yes Yes No Yes yes yes
JDX 4.5 No No Yes Yes No JDBC * Yes * Yes No * Yes Yes Yes * Yes Yes Yes Yes Yes Yes Yes Yes No * Yes No * No No No * Yes * No Yes No Yes Yes Yes ? ? ?
Lychee 0.01 Yes Yes No Yes No JDBC No Yes Yes No Yes No No Yes No Yes Yes No No Yes Yes No JDBC No No No Yes No No No Yes Yes Yes Yes Yes No Yes Yes Yes
KodoJdo 3.3.3 No * No Yes * Yes No JDBC * Yes * Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes * Yes Yes No No Yes Yes No Yes Yes ? Yes Yes Yes ?
Signsoft intelliBO 3.6 No * No Yes Yes No JDBC * Yes * Yes No No * Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes No No Yes * Yes No Yes * Yes No * Yes Yes Yes No
SimpleOrm 0.1 Yes * Yes * No * No * No * JDBC * * Yes * Yes * Yes * Yes * Yes * Yes Yes * Yes No * No * Yes * * Yes * No * Yes * Yes No * No * No * No * No No * Yes * Yes * Yes * No ? ? ?
The ProductivityEnvironmentForJava (PE:J) 2.2.2 Yes * No Yes Yes No JDBC * Yes * Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes No * Yes Yes Yes No Yes * Yes Yes * No Yes Yes Yes Yes ? ? ?
TopLink 9.03 No * No * Yes Yes No * JDBC * Yes * Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes * Yes * Yes No * No No Yes * No Yes Yes * Yes * Yes Yes ? Yes Yes
VBSF 3.03 No No Yes Yes No JDBC * Yes * Yes Yes * Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes No Yes Yes Yes * Yes * No Yes * No Yes Yes Yes Yes Yes ? ? ?
XIC 4.2 No No Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes

Features included in the comparison:

0. Relationally Complete.

1. Release Version Number (To indicate which version has been referred to)

2. "Free" as in "free beer" - no license fee

3. "Free" as in "free speech" - source available

4. Has mapping GUI

5. Persists arbitrary classes (no special superclass or interface required)

6. Requires manual SQL building

7. RDBMS support/independence

8. EJB support (for whoever needs it)

9. Supports relationships between objects

10. Mapping supports grouping (GROUP BY clause)

11. Mapping supports aggregate functions (count(), avg(), etc.)

12. Includes full support of lazy resolution of all queries

13. Maintains single identities for objects returned from queries (aka "uniquing") (i.e., AddressFinder.findById(1) == AddressFinder.findById(1));

14. Resolves Circular Identities (aka "uniquing") (i.e., "account == account.getCustomer().getAccount()")

15. Generates Mapping as well as the Java Objects themselves, so you don't duplicate information in the Java Objects and the related mapping information. Comments: (who says this is a GoodThing? I don't want my DomainObject classes' source generated by some tool)

Well, for O/R mapping you have to define somewhere the fields and how they're persisted. This usually at least consists of class, field names, and types. If you write the class and the mapping, you violate OnceAndOnlyOnce and DontRepeatYourself since the mapping file duplicates all the information that is contained in the class itself. The mapping gives you all the information you need to generate the object itself, so why not generate it? Why write code that you don't have to? There's a difference between a DomainObject and a DataAccessObject. DomainObjects have behavior-intensive methods that implement various responsibilities allocated to them from application requirements. Is the mapping tool going to generate the code for all my DomainObject's responsibilities? I doubt it. It probably generates only a simple class skeleton consisting of variable declarations and getters and setters - which I may not even want. And it probably can't preserve non-generated additions when the need arises to re-generate due to class shape or mapping changes. The DomainModel is the heart of the system - see http://domainlanguage.com/book.html - and can be written and tested before any persistence-related code is even written. Plus, what happens if you want to switch persistence technologies, such that your mapping and the tool that generates it becomes irrelevant? Many of the problems you describe relate to PassiveCodeGeneration and not ActiveCodeGeneration (regenerate at every build, NEVER MODIFY). There are ways to effectively merge business logic and generated objects. Basically it boils down to inheritance or composition, either one is effective. This is often called a the MartiniGlassArchitecture b/c it allows you to seamlessly (ThereIsNoSuchThingAsSeamless) merge business and generated data logic into one unified DomainModel. Any tool, whether a language or a code generator, (Java and CeeSharp can also be viewed as code generators) can become obsolete. Evaluate your risks accordingly. Preferably, find an open source solution, get write access, then make sure it doesn't become obsolete. ;)

16. Supports Composite Primary Keys

17. Aggregate Mappings - Single field maps to multiple fields in database. http://martinfowler.com/eaaCatalog/embeddedValue.html'''

18. Supports both many to many and one to many associations

19. Supports collections of Strings, Integers, Dates, etc

20. Supports inheritance / polymorphic queries

21. Supports one to one associations

22. Can fetch associated objects using SQL outer joins

23. Support for optimistic locking / versioning

24. Support for Unit of work / object level transactions

25. Providing a SUN JDO compliant API

26. Providing an ODMG compliant API

27. Requires "extra" database tables holding locks, metadata, etc.

28. Supports multiservers (clustering) and simultaneous access by other applications without loss of transaction integrity

29. Requires code generation / bytecode processing

30. Requires RuntimeReflection

31. Query Caching - Built-in support (developer writes no code). The following two identical queries will hit the database only once. The second time cached results will be returned.

Address address = AddressFinder.selectByPrimaryKey(new Long(1));

assertTrue(address == AddressFinder.selectByPrimaryKey(new Long(1)));

32. Supports sequences and identity/autoincrement columns for primary key generation (Not using the incorrect SELECT MAX method!)

33. Supports ternary associations

34. Supports mapping of one class to multiple tables

Comments: Any comments on this? Is this really a useful thing to do? If the tables are badly designed, fix them!
I believe why this question can is solve by convenient UML diagram
We think this is a Bad Thing: http://www.hibernate.org/Documentation/Delegate
Sometimes legacy databases leave you no choice.

I believe that for a general purpose persistence framework, this type of support is absolutely critical. The reason is that in many development shops, different people control the object and data models. In the real world, either or both could be well designed or poorly designed. Either or both could be a legacy model, or new.

Even with good design this is desirable. Object modeling and relational modeling represent the same conceptual model differently - they cannot be expected to be 1 for 1. For example, tables are needed for many to many relationship - a class is not needed for this, as each object merely has a collection of the other.

35. Supports mapping of multiple classes to one table

36. Supports persistence of properties through private fields

37. Supports persistence of properties through accessors (get/set methods)

38. Supports disconnected operations: Populate objects from database, disconnect, create/remove/modify objects (on client, another JVM) and apply changes to database (much) later

Comments and explanations of the features

1. Release Version Number (To indicate which version has been referred to)

2. "Free" as in "free beer" - no license fee

3. "Free" as in "free speech" - source available

4. Has mapping GUI

5. Persists arbitrary classes (no special superclass or interface required)

6. Requires manual SQL building

7. RDBMS support/independence

8. EJB support (for whoever needs it)

9. Supports relationships between objects

10. Mapping supports grouping (GROUP BY clause)

11. Mapping supports aggregate functions (count(), avg(), etc.)

12. Includes full support of lazy resolution of all queries

13. Maintains single identities for objects returned from queries (aka "uniquing") (i.e., AddressFinder.findById(1) == AddressFinder.findById(1));

14. Resolves Circular Identities (aka "uniquing") (i.e., "account == account.getCustomer().getAccount()")

15. Generates Mapping as well as the Java Objects themselves, so you don't duplicate information in the Java Objects and the related mapping information.

Comments: (who says this is a GoodThing? I don't want my DomainObject classes' source generated by some tool)

Well, for O/R mapping you have to define somewhere the fields and how they're persisted. This usually at least consists of class, field names, and types. If you write the class and the mapping, you violate OnceAndOnlyOnce and DontRepeatYourself since the mapping file duplicates all the information that is contained in the class itself. The mapping gives you all the information you need to generate the object itself, so why not generate it? Why write code that you don't have to? There's a difference between a DomainObject and a DataAccessObject. DomainObjects have behavior-intensive methods that implement various responsibilities allocated to them from application requirements. Is the mapping tool going to generate the code for all my DomainObject's responsibilities? I doubt it. It probably generates only a simple class skeleton consisting of variable declarations and getters and setters - which I may not even want. And it probably can't preserve non-generated additions when the need arises to re-generate due to class shape or mapping changes. The DomainModel is the heart of the system - see http://domainlanguage.com/book.html - and can be written and tested before any persistence-related code is even written. Plus, what happens if you want to switch persistence technologies, such that your mapping and the tool that generates it becomes irrelevant? Many of the problems you describe relate to PassiveCodeGeneration and not ActiveCodeGeneration (regenerate at every build, NEVER MODIFY). There are ways to effectively merge business logic and generated objects. Basically it boils down to inheritance or composition, either one is effective. This is often called a the MartiniGlassArchitecture b/c it allows you to seamlessly (ThereIsNoSuchThingAsSeamless) merge business and generated data logic into one unified DomainModel. Any tool, whether a language or a code generator, (Java and CeeSharp can also be viewed as code generators) can become obsolete. Evaluate your risks accordingly. Preferably, find an open source solution, get write access, then make sure it doesn't become obsolete. ;)

Note that this problem can be side-stepped if you're using a language with decent RuntimeReflection, like RubyLanguage, PythonLanguage, or SmalltalkLanguage. -- francis

16. Supports Composite Primary Keys

17. Aggregate Mappings - Single field maps to multiple fields in database. http://martinfowler.com/eaaCatalog/embeddedValue.html'''

18. Supports both many to many and one to many associations

19. Supports collections of Strings, Integers, Dates, etc

20. Supports inheritance / polymorphic queries

21. Supports one to one associations

22. Can fetch associated objects using SQL outer joins

23. Support for optimistic locking / versioning

24. Support for Unit of work / object level transactions

25. Providing a SUN JDO compliant API

26. Providing an ODMG compliant API

27. Requires "extra" database tables holding locks, metadata, etc.

28. Supports multiservers (clustering) and simultaneous access by other applications without loss of transaction integrity

29. Requires code generation / bytecode processing

30. Requires RuntimeReflection

31. Query Caching - Built-in support (developer writes no code). The following two identical queries will hit the database only once. The second time cached results will be returned.

Address address = AddressFinder.selectByPrimaryKey(new Long(1));

assertTrue(address == AddressFinder.selectByPrimaryKey(new Long(1)));

32. Supports sequences and identity/autoincrement columns for primary key generation (Not using the incorrect SELECT MAX method!)

33. Supports ternary associations

The "ternary relationship" entries look a bit misleading. Please double check that, and provide documentation. For example TopLink and ObjectRelationalBridge provide no easily accessible official documentation of how they support such a feature (if indeed they support), or if they provide that they keep it very well hidden. Workarounds do not qualify as support, I'd expect that the same documentation that provides extended discussion of One to One, One To Many and Many to Many (usually mapped to first class objects in the API, and first class entities in the XML configuration file ) should provide a clarifying example/discussion of n-ary relationship concept, backed by the corresponding entry in the API or XML.

For whatever reason ObjectRelationalMapping makes for lots of passion, witness the inordinate amount of open source projects, a sign that a great deal of good developers preferred a "roll your own" solution. So we need to try to keep this discussion relatively to the level of a little more than marketing material checkboxes.

34. Supports mapping of one class to multiple tables

Comments: Any comments on this? Is this really a useful thing to do? If the tables are badly designed, fix them!
I believe why this question can is solve by convenient UML diagram
We think this is a Bad Thing: http://www.hibernate.org/Documentation/Delegate
Sometimes legacy databases leave you no choice.

I believe that for a general purpose persistence framework, this type of support is absolutely critical. The reason is that in many development shops, different people control the object and data models. In the real world, either or both could be well designed or poorly designed. Either or both could be a legacy model, or new.

35. Supports mapping of multiple classes to one table

36. Supports persistence of properties through private fields

37. Supports persistence of properties through accessors (get/set methods)

Other questions

38. Supports disconnected operations: Populate objects from database, disconnect, create/remove/modify objects (on client, another JVM) and apply changes to database (much) later

39. Supports logging all the executed SQL statements in a SQL file ?

40. Supports an API allowing to invalidate part of the cache (for example when the database is updated directly)?

41. Supports massive updates (with batch and transaction size tuning)?

42. Supports Date/Timestamp mapping with correct time zone?

43. Supports mapping of immutable objects?


See also FavoriteObjectRelationalTools