Choosing a Java Persistence Strategy
Java persistence techniques and technologies remain a hot topic in the Java community. With so many approaches and products it really must be a bewildering subject for a novice Java developer. How does one choose between the various standard technologies (e.g. JDBC, JDO, EJB 2, and EJB 3), open source technologies (e.g. Hibernate, OJB, and iBATIS), and commercial products (e.g. Oracle TopLink)?
With this in mind I thought it would be useful for me to write a brief guide to choosing the right persistence approach for various scenarios – because one size most certainly does not fit all.
At the point where a Java developer decides that he or she needs a persistence technology, they are likely to have already chosen (possibly subconsciously) one of three approaches, which I choose to call "Java First", "Database First", or "Spaghetti Junction". I describe these approaches as:
1. They have developed some Java code and need somewhere to store their objects ("Java First")
2. They have designed (or inherited) a database and want to write Java code to access it ("Database First")
3. They have a database and some Java code and now they want to connect the two together ("Spaghetti Junction")
My preference is "Database First" since I find that database design tools are better suited to designing high-performance relational data models than using UML or Java as a starting point. This may not be so important for smaller projects.
The approach taken often dictates which technologies and tools are most appropriate.
Approach 1 – "Java First"
If the Java object model is already written then it has most likely been written without thought for persistence. In other words the object model consists of normal Java classes. In persistence circles, this is often referred to as the POJO (Plain Old Java Object) pattern. The open source Hibernate project has become a highly popular choice for persisting POJO objects to a database (Hibernate can generate the database schema as well). The "Java First" approach precludes the use of EJB 2 unless the code has been designed from the start with EJB in mind.
Approach 2 – "Database First"
If the database already exists then it is a case of writing a Java object model to match the database schema and this scenario offers the widest range of choices. However, whichever technology is chosen there is a common need to re-invent the wheel and design the data model again but in Java this time. Using a code generator such as FireStorm/DAO can greatly speed up productivity by automatically generating a complete persistence tier (Java code and associated configuration/mapping files) directly from the database schema. This approach can be used regardless of choice of JDBC, JDO, EJB, Hibernate and so on.
Approach 3 – "Spaghetti Junction"
If a Java object model and a database schema already exist then the common approach would be to use an object-relational mapping product (e.g. Hibernate, iBATIS, Oracle TopLink, etc.) to build a mapping layer. When used in this way the mapping tier can become highly complex and expensive to maintain.
Another often overlooked approach is to use the "Database First" approach and generate a Java API from the database, then write adapters from the "legacy" Java object model to the new object model. This at least changes the problem from an object-relational mapping issue to an object-object mapping issue (don't we deal with those all the time?).