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
IncludesMaintainsGeneratesSupportsSupportsSupportsCan fetchSupports  SupportsRequiresSupportsSupportsSupportsSupports 
RequiresSupportsMappingfull support singlemappingSupportsboth manycollections  inheritanceassociated  optimistic SupportsProvides  ProvidesRequiresclusteringcodesequences andmappingmappingpersistenceSupports
Free -Free -  PersistsmanualRDBMS supportrelationsMappingsupportsof lazyidentities Resolvesascompositeto many and  of Strings,  /Supportsobjectslockingunit of work/ SUN JDOODMGdatabasewithoutgeneration  Requiresautoincrements Supportsclass tomultiplethroughpersistence
Releaseno licence sourceHas mapping  arbitrarySQL/betweensupports  aggregateresolutionforcircularwell asprimaryAggregate one to oneIntegers,polymorphic  one to oneusing/  object level  compliant complianttables for loss of/ byteruntimeQueryfor primaryternarymultipleclasses to privatethrough
Versionfeeavailable  GUI  classesbuilding  independence  EJB supportobjectsgrouping  functionsof queriesobjectsidentities objectskeysmappings  associations Dates, etc.  queriesassociations  outer joins versioning transactions  APIAPI metadatatransactions  processing  reflection Caching key generation associations tablesone table  fieldsaccessors
          1. 2 3 456 78910111213 14 1516171819202122 23 242526 27 2829 30 31323334 35 3637

Abra00.9.6YesYesNoNoNoJDBC *No *Yes NoNoYes *Yes *YesYes *No *No *Yes No *Yes *YesNoYesYesNoNoNoYesYes NoYes *Yes?No *Yes *NoYes * BasicWebLib0.7iYesYesNoNoYes *?*YesYesYesNoNoNoNoYesYesYesYesYesYesYesNoNoNoNoNoNoNo No NoYes?No ??? Castor0.9.5YesYesNoYes * NoJDBC *No *Yes NoNoYes *Yes?NoYesYes *YesYes NoYesYesYes *YesNoYesNo ?No YesYes *Yes * ?Yes *No NoYes CayenneFramework1.1YesYesYesNoNoJDBC *Yes *YesYesYesYes *Yes *YesYesYes? Yes *??YesNo *Yes *?NoNoYes *??? ???? ??? CocoBase4NoNoYesYesNoJDBC *Yes *Yes ?YesYes??YesYesYesYesYesYesYesYes *YesYesNoNoNo?NoYesYes *??? ? ?? DataBind0.4YesYesNoYesYes *JDBC *NoYesYesNoNo NoNoYesNoNoNo??NoNoNoNoNo ?NoNo YesNo?????? EdgeXtend2*NoNoYesNo *NoODBC *Yes *YesNo *No *Yes *YesYesYesYesYesYes *No *YesYesYesYesYesNo *NoNoYesYesNoNo *YesNo? Yes *?? EnterpriseObjectsFramework?No *NoYesNoNoJDBC *No *Yes No *No *Yes *Yes *YesYesYesYes *Yes?Yes *No *YesYes *YesNoNoYes *?NoYes *Yes *Yes * ?Yes *Yes?? Expresso?YesYesNoNoNoJDBC *Yes *YesYesYes???YesYesYesYes ?????YesNoNoNoNo *No????? ? ?? FireStormNo * FrontierSuite? for J2EE & J2SE3.1NoNoYesYesNoJDBC *Yes *Yes NoYesYesYesYesYes *YesYesYesYesYes *YesYesYesYesNoNoNoYes *YesYesYesYesNoYes??? FrontierSuite? for JDO3.0 SP1NoNoYesYesNoJDBC *Yes *YesNoNo *Yes *YesYesYes *YesYesYesYesYes *YesYesYesYesYesNoNoYes *YesYesYesYesNoYes??? Hibernate3.0.2YesYesNo *YesNoJDBC *Yes *YesYesYesYes *Yes *YesYes *Yes *YesYesYes *Yes *Yes *Yes *Yes *YesNoYes *No *Yes *Yes *No *Yes *Yes *Yes *Yes (3)YesYesYes iBATIS DB Layer2YesYesNo *Yes *Yes *JDBC *Yes *YesYes *Yes *Yes *NoNo NoYes *Yes *YesYesNoYesYesNo No * No *NoNo NoNo *YesYes *Yes * ?Yes *Yes?Yes Infobjects ObjectDRIVERYesNo No NoYesNoODBC *No * Yes NoYesYes YesYesYesYesYesYes Yes Yes YesNo YesYesNo *Yes No YesNo No YesYesYes Yes? ?? InterSystems Cache5.0RC3 JDBC *Yes *Yes *?Yes * ?? ?Yes *Yes *? ?????? ?????? ? ?? Jakarta ObjectRelationalBridge1YesYesYes *YesNoJDBC *Yes *YesYesYesYes *YesYesYesYesYesYesYesYesYesYes Yes *YesYes *Yes *No *YesNo *No *Yes *Yes *YesYesYesYesYes Java Ultra-Lite Persistence (JULP)1.0.1yesYesYesNoYesYesYesYesYesYesNo?NoYesYes *Yes?YesYesYesYesYes *NoNoNoNoNoYesYesYes?Yes ?YesYes JaxorFramework2.2YesYesNoNo *NoJDBC *Yes *YesYes?Yes *YesYesYesYesYesYesYesYesYesYes *Yes *Yes * ? ?NoYesYesNoYes *??? ? ?? JdoGenie1.3.2No *NoYesYesNoJDBC *Yes *YesNoNoYes *YesYesYes *YesYes *YesYesYesYesYes *Yes *YesYesNoYes *Yes *Yes *NoYes *Yes?? ? ?? JdoMax1.0YesNoNoYesNoyesNoYesNoYesYesYesYesYesNoYesYesYesYesYesYesYesYesYesNoNoNoYesNoYesYesYesYesYesYesYesNoYesyesyes JDX4.5NoNoYesYesNoJDBC *Yes *Yes No *YesYesYes *YesYesYesYesYesYesYesYesNo *YesNo *NoNoNo *Yes *NoYesNoYesYesYes? ?? Lychee0.01YesYesNoYesNoJDBCNoYesYesNoYesNoNoYesNoYesYesNoNoYesYesNoJDBCNoNoNoYesNoNoNoYesYesYesYesYesNoYesYesYes KodoJdo3.3.3No *NoYes *YesNoJDBC *Yes *YesYesYesYesYesYesYesYesYesYesYesYesYesYesYes *YesYesNoNoYesYesNoYesYes?YesYesYes? Signsoft intelliBO3.6No *NoYesYesNoJDBC *Yes *YesNoNo *YesYesYesYesYesYesYesYesYesYesYes YesYesYesNoNoYes *YesNoYes *YesNo *YesYesYesNo SimpleOrm0.1Yes *Yes *No *No *No *JDBC **Yes *Yes *Yes *Yes *Yes *YesYes *YesNo *No *Yes **Yes * No *Yes *YesNo *No *No *No *NoNo *Yes *Yes *Yes *No ? ?? The ProductivityEnvironmentForJava (PE:J)2.2.2Yes *NoYesYesNoJDBC *Yes *YesYesYesYesYesYesYesYesYesYesYesYesYesNo *YesYesYesNoYes *YesYes *NoYesYesYesYes? ?? TopLink9.03No *No *YesYesNo *JDBC *Yes *YesYesYesYesYesYesYesYesYesYesYesYesYesYes *Yes *YesNo *NoNoYes * NoYesYes *Yes *YesYes? YesYes VBSF3.03No NoYesYesNoJDBC *Yes *YesYes *YesYesYesYesYesYesYesYesYesYesYesNoYesYesYes *Yes *NoYes * NoYesYesYesYes Yes? ?? XIC 4.2 NoNoYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYes

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
 * SpadeSoft XJDO: Yes (version numbers, timestamp, user defined versioning)
24. Support for Unit of work / object level transactions
 * SpadeSoft XJDO: Yes 
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
 * SpadeSoft XJDO: Yes (Built in enhancer or any standard JDO enhancer)
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


EditText of this page (last edited October 16, 2012) or FindPage with title or text search