Enterprise applications often deal with operations such as the collecting, processing, transforming, and reporting of a large amount of data. These data are typically stored in a database server in a particular location and retrieved on demand. The application is responsible for processing the data from the database and finally present them for client consumption. But, the intricacies involved in mitigating the data exchange between different architectures is the real challenge that developers face. The heart of the problem lies in easing the complicated relationship of data movement between the code used to develop the application and the storage model used for data persistence. In short, the idea is to create a mechanism for seamless interaction between two unyielding models: the object-oriented nature of the Java language and the relational database model.
Basic APIs for Databases
The Java platform already has standard APIs to work with database systems in the form of JDBC APIs. These APIs are excellent at working with the database and provide the means necessary to interact with the database conveniently from the Java language. But, the problem is that Java is an object-oriented language. The JDBC provides core APIs for database interaction and is not focused in transforming the row and column structure of the database table into an entity class. Therefore, a layer of API is sought that works above the JDBC API. The persistence API, or JPA, mitigates two architecturally different models with the goal of leveraging fluidity of operation. The API helps represent a database relation table as a POJO and can be treated in a like manner all through Java code. The core JDBC API works in the background to deal with the intricacies of communication and database connection whereas JPA enables the dealings to be done according to the object-oriented code of the Java language. However, the data mapping between relational database and Java is not an easy task.
Java Persistence Support
In a typical relational database, information is stored in a row and column structure. The exchange of data between a database system and the object model of the Java application is difficult because Java designates a single entity as a class denoted by a set of properties and operations applied on them. Therefore, to conform a behavioral mismatch between the two different architectures, a Java programmer has to write many lines of code. These lines of code help transform the row and column data of the database table in to Java objects. But, often these lines of code become too repetitive, resulting in the source code replete with boilerplate codes. This is undesirable and violates the basic object-oriented principle of reusability. Although clever codes may mitigate many of the adversity, it is not an easy solution. The emergence of third-party solutions is a respite in mapping database data into Java objects but they were not standard. Each vendor implementation varied considerably from another. This all means that the situation demanded a standard persistence API library from the Java platform itself. This led to the introduction of Java Persistence API (JPA), especially to bridge the gap between object-oriented domain model of Java and the database system.
Understand that object-relational solutions have been around for quite some time, dating even back before the birth of the Java language itself. For example, the TopLink product of Oracle actually kickstarted with Smalltalk, and then later switched to Java. Today, it is a part of the OracleAS, WebLogic, and OC4J servers. In fact, the two most popular persistence APIs used to be Oracle’s TopLink, a proprietary standard in the commercial domain, and Hibernate in the open source community domain. Later, Hibernate became more popular and heavily influenced the creation of the standard JPA library.
A data mapper is basically an architectural pattern proposed by Martin Fowler in his book Patterns of Enterprise Application Architecture, 2003. It provides a partial way to address the object-relational problem. The mapper helps create a strategy that falls into the category between plain JDBC and a full-functional object relational mapping solution. Here, application developers create a raw SQL string to map database tables to Java objects by using the data mapper method. There is a popular framework that uses this technique of mapping between SQL database and Java object, called Apache iBatis. The Apache iBatis project has been declared to be inactive now. However, the original creators of Apache iBatis have transferred the project to MyBatis and is under active development.
Unlike other object-relational problem solutions using the data mappers framework like MyBatis, we can have complete control over SQL transactions with the database. It is a lightweight solution and does not carry the overhead of a full-blown ORM framework. But, there is a problem with data mappers. Any changes made to the object model have repercussions on the data model. One has to make significant changes to the SQL statements directly as a consequence. The minimalistic nature of the framework helps developers incorporate new changes and modifications according to the need. Data mappers are particularly useful in a situation where we need a minimal framework, explicit SQL handling, and more control for developer modification.
The JDBC (Java Database Connectivity) is a Java-specific version of Microsoft’s ODBC (Object Database Connectivity) specification. The ODBC is a standard for connecting any relational database from any language or platform. JDBC provides similar abstraction with respect to the Java language. JDBC uses SQL to interact with the database. Developers must write DDL or DML queries as per the syntactical specification of the backend database, but process them using the Java programming model. There is a tight coupling between the Java source and the SQL statements. We can resort to raw SQL statements and manipulate them statically according to need. Due to its static nature, it is difficult to incorporate changes. Moreover, SQL dialects vary from one database vendor to another. JDBC is hardwired to the database and not to the object model of the Java language. Therefore, it soon feels cumbersome to work with, especially when database interaction from Java source code increases. However, JDBC is the primary support for database persistence in Java and forms the basis for high-level frameworks.
The Enterprise Java Bean (EJB) with J2EE brought some new changes in the arena of Java persistence in the form of the entity bean. The idea was to isolate developers from directly intervening with the intricacies of database persistence. It introduced an interface-based approach. There is a specialized bean compiler to generate the implementation for persistence, transaction management, and business logic delegation. Specialized XML deployment descriptors were used to configure the entity beans. The problem is that EJB, rather than simplifying things, incorporated a lot of complexity. As a result, despite numerous subsequent improvements such as introduction of Enterprise JavaBeans Query Language (EJB QL), it soon lost popularity.
Java Data Object
The JDO (Java Data Object) tried to address the problem faced by the EJB persistence model. It provides an API for transparent persistence and is designed to work with EJB and J2EE. JDO is a product heavily influenced and supported by object-oriented databases. Persistence objects are plain Java objects that do not require a developer to implement any special class or interface. Object persistence specifications are typically defined in an XML metafile. The query languages supported are object-oriented in nature. In spite of many good features, the JDO specification could not grab much acceptance among the developer community.
Java Persistence API
There were a number of proprietary persistence frameworks both in the commercial domain and open source domain. Frameworks such as Hibernate and TopLink seemed to meet the application need quite nicely. As a result, Hibernate was picked as a primary basis for creating a standard persistence model called JPA.
JPA is a standard lightweight Java persistence framework that helps create object relational mapping using POJO. JPA also helps integrate persistence into a scalable enterprise application. It is easy to use because there are only a small number of classes that need to be exposed to an application interested in using the JPA persistence model. The use of a POJO is perhaps the most intriguing aspect of JPA. It means that there is nothing special about the object; that makes it persistable. The object-relational mapping is metadata driven. It can be done either by using annotation internally within the code or externally. by using XML.
The persistent APIs of JPA exist as a separate layer from the persistent object. The business logic typically invokes the API and passes the persistent object to operate upon them. Although the application is aware of the persistent API, the persistent object, being POJO, is completely unaware of its persistence capability.
This article gave an overview of some of the proprietary solutions available prior to the introduction of JPA, such as data mapper, JDBC, and EJB. The idea is to give an insight into what led to the creation of JPA, and a little bit about its predecessor’s persistent technique. Stay tuned; subsequent articles delve into more specific aspects of the JPA API.