More Object Persistence Choice Factors
In this second of four installments, object query mechanisms and transaction state management are discussed as critical factors in deciding on the right object persistence technology.
By Dr. Wilson Cheng and Dr. Pinaki Poddar
In the first installment of this discussion, "Choose the Right Object Persistence" (Java Pro online, July 16, 2003), we covered the mapping support and domain models of JDBC, CMP, and JDO as factors you should consider in deciding on your object persistence technology. Now let's turn to object query mechanisms and transaction state management as additional factors in your decision.
In general, existing objects in a data store are accessed more frequently than new objects are created. The object query mechanism is therefore another critical issue in object persistence. Important factors characterizing a query mechanism are: How does an application specify a database query? How powerful is the query expression language? And, in what form does the data store return query results? JDBC uses SQL, CMP uses EJB-QL, and JDO uses JDO-QL. These query mechanisms are unique.
The most important difference is that while SQL queries refer directly to the data store schema, both EJB-QL and JDO-QL specify the query in their object models. The second critical difference is the way a query is specified. JDBC applications send a query directly to the data store as String arguments to the methods of java.sql.Statement.
Queries in EJB are declarative—abstract finder methods on the bean interface. The deployment descriptor defines how the finder is realized in EJB-QL. The EJB compiler translates an EJB-QL query to the syntax of the target data store. The compiler also inserts execution statements in the automatically generated concrete bean class.
Queries in JDO follow a programmatic approach using Java-like syntax. A JDO query is represented as an instance of a javax.jdo.Query object, with predicates, parameters, and variables specified on a Query instance. Predicates, parameters, and variables refer only to elements in the Java application space; the JDO driver at runtime translates the query into the syntax of the target data store when the execute() method is invoked on a Query object.
Aggregational queries compute statistics of sets of records and are natural to RDBMSs designed for set operations. JDBC and SQL perhaps remain unsurpassed in power of expression for selecting RDBMS records with aggregational queries. The major benefit is that computational load is on the RDBMS. For example, to compute the average salary of all employees, a JDBC application issues a single SQL statement, the RDBMS server computes the average, and the JDBC driver returns a single number. Compare this streamlined process to application-centric query mechanisms such as EJB-QL or JDO-QL, in which the average salary computation results in fetching employee instances from the data store to the client, where computation occurs.
A navigational query is the capability of accessing related instances from a given instance. For example, a particular department might be selected, and then an employee of that department is needed. In the domain model, the Department object contains the Employees as a collection. In such cases, as application code iterates through the collection of Employees, a CMP or JDO driver implicitly fetches Employee instances from the data store, but with JDBC the application must issue an explicit SQL query to fetch Employee records.
Will EJB-QL or JDO-QL ever match SQL's power? EJB-QL is approaching SQL-like syntax and capabilities. JDO queries also allow alternative syntax in a particular JDO driver. In principle, a JDO driver for RDBMS may allow your application to use direct SQL. However, the design focus in CMP and JDO is to separate the domain object model from the schema and data store. As such, CMP and JDO cannot assume specific query capabilities of the data store.
Query Results
Ad-hoc queries are constructed dynamically at runtime from users' specifications. JDBC and JDO can construct ad-hoc queries either dynamically—generating SQL statements—or programmatically by configuring predicates and variables of a javax.jdo.Query instance. EJB declarative mechanisms, however, cannot form ad-hoc queries because finder methods are created during design but not realized until compilation. The only limited configuration available to EJB queries is to bind parameters to queries at runtime.
Another important difference is how query results are returned to the application. SQL query results are returned as java.sql.ResultSet, an iterator over a collection of database records. Each record is a set of name/value pairs, not a domain object. The developer must extract each value from the result set and populate the correct fields of an object instance.
Query mechanisms in CMP and JDO, by contrast, return query results as domain objects. In EJB, the returned instances are a collection of beans; in JDO, they are a collection of objects of a type defined by the query's candidate class. The application developer only needs to cast the result objects to appropriate domain classes. The overhead of marshalling query results to domain objects (as with JDBC) is built into CMP and JDO.
An object persistence service should track the transaction state of domain objects to assist the complex logic of enterprise applications.
Transaction state means whether the object has been created, modified, or deleted in the current transaction. Transaction boundaries in applications often span multiple method invocations. As a consequence, one method might have no knowledge of whether an object has been modified by another method during the same transaction. Such information is critical, as business logic grows more complex.
Developing consistent transaction semantics in an enterprise application is always challenging, and developing configurable transaction logic is even more difficult.
Even when an application does not explicitly track transaction state, the driver itself can make use of such features to provide advanced services such as persistence by reachability, automatic tracking of modified objects for commit, or selective update of fields. When a transaction is committed to a data store, for example, automatic transaction state management can improve performance by synchronizing the state of only modified objects, rather than all objects in the transaction. This set of objects that must be committed is called commit closure. Developers can explicitly mark the transaction state of objects to identify the commit closure, but such explicit state tracking is prone to errors.
JDBC has no facility to track the intermediate transaction state of objects. The application itself must keep track of the objects that have been modified or created within a transaction. In complex transactions that modify a set of related entities, the application developer must maintain data consistency by synchronizing the updated fields of the objects to the database at the transaction boundary.
State Management
CMP manages state from the perspective of the EJB container and not from that of the transaction. The container calls EJB life-cycle methods when it is passivated in temporary storage or loaded from the data store. But asking an entity bean whether it has been modified within the current transaction is not possible. A CMP provider can track bean transaction state, so that only modified records are committed, but this management is left to the vendor and not mandated by the EJB specification.
CMP provides advanced declarative transaction semantics. Declarative transactions through deployment descriptors can control the transaction context in which a bean method is invoked. For example, if method m1 of bean B1 invokes method m2 on another bean B2, it is possible to specify that m1 and m2 are executed in either the same or a separate transaction context.
JDO's transaction state management is strong. Any persistent object managed by JDO is in a specific, queryable state in a transaction. You can thus detect modified objects. However, an application developer does not often need to be concerned with such details. Instead, the JDO providers have advanced features such as persistence by reachability, automatic tracking of updated instances, optimistic locking, and more.
With JDO's persistence by reachability, an application can identify a "root object" that relates to a whole set of objects and mark this "root object" as persistent. Persistence by reachability ensures that at transaction completion the set of modified objects reachable from the root object is committed to the data store. This service is transparent to the application, completely independent of any application code. For example, consider a simple method that constructs a Department instance and adds four new Employee instances to its collection of Employees. If the Department is marked persistent, the four new Employees become persistent automatically by virtue of their reachability from the Department. At transaction commit, JDO automatically inserts one new Department record and four new Employee records in the data store without explicit instruction by the application.
Upcoming postings will discuss performance and scalability, portability, mechanics, and how to choose the technology that best meets your needs.
About the Authors
Dr. Wilson Cheng, vice president engineering, directs product development strategies and initiatives at Versant Corporation; has led interdisciplinary, intercompany teams to improve cross-platform e-business solutions at Oracle; and was the chief architect for the object replication project for Jasmine at Fujitsu. Cheng published more than 20 technical articles in various international conferences and was the program chair for the sixth annual Australian Conference on Parallel and Real-Time Systems. Dr. Pinaki Poddar, principal software engineer for Versant Corporation, works in the area of object persistence and J2EE integration. He designed enterprise applications for the health care and finance industries and developed a Hindi speech recognition system in his past life. He is also a contributor to www.openadaptor.org, an open source project for enterprise application integration. Reach Wilson at , and reach Pinaki at .
|