Understanding pureQuery, Part 1: pureQuery: IBM's new paradigm for writing Java database applications

Save time, write little code, run everywhere

The project called pureQuery gives database application developers an easy, GUI-based means to significantly increase productivity in both the design and implementation phases. This is accomplished through user-initiated automatic transformation of relational data into Java™ objects for access and manipulation of data. In turn, these objects can be seamlessly utilized in a natural object-oriented (OO) programming paradigm to write the business logic and the underlying code. pureQuery's functionality in effect eliminates traditional JDBC programming by integrating the query language with Java itself. This article is part 1 of a series of articles on this topic.

Azadeh Ahadian (azadeh@us.ibm.com), Eclipse Application Development Tools , IBM

Photo: Azadeh Ahadian Azadeh Ahadian is a software developer in the Information Management tool organization at IBM’s Silicon Valley Lab in San Jose, Calif. She has a Master's degree with more than eight years of industry experience in software application and tools development. Azadeh has been a key contributor and a member of the pureQuery design time team.



14 December 2007 (First published 16 August 2007)

Also available in Chinese Japanese

Note:

This article is currently in the process of being updated. For the most up-to-date information on pureQuery, visit the IBM pureQuery platform page on ibm.com.

Introduction

The objectization of relational data access

Most businesses are built on information management systems whose main underlying infrastructures are based on data stored in one or more relational databases. These systems consist of software programs whose sole purpose is information processing and are implemented in managed languages such as Java.

As an OO-based language characterized by ease of use for encapsulation, inheritance and polymorphism, Java is used on the one hand to implement the computational and logical aspects of information processing programs, and on the other hand to access and manipulate relational data. Java defines information in terms of objects, while relational databases use rows. Objects are unique instances of the class to which they belong, and hence they are physically distinct from one another. Similarly, relational database rows are also unique, so long as they are identified by primary key values. On the other hand, objects do stand alone and continue to exist so long as they are still referenced by one or more other objects. Rows however exist as elements of tables, and are eliminated as soon as they are removed.

Therefore, while objects and rows are similar in many aspects, the intrinsic value of objects to modular programming in the interest of scalability, extensibility, and efficient code maintenance has been the basis for design fundamentals to abstract the relational row layer through objectization. We define objectization as the process of bringing OO's fundamental concepts of encapsulation, inheritance, and polymorphism to an otherwise intensive instructional, in-line data query practice performed using SQL. In short, objectization is the process of creating seamless objects with methods capable of performing database operations (including create, replace, update and delete), in a pure OO paradigm.

The most popular way to objectize to programmatically access and manipulate relational data has been through special APIs and wrappers that provide one or more SQL statements written as text strings. The entire relational data processing is based on these encapsulated SQL statements, and they are significant portions of the program logic. However these SQL statements are not transparent to the Java language and therefore are unable to benefit from compile-time optimization and semantic and syntax verification -- not to mention being left out of design-time features such as content assist that collectively provides tremendous time saving assistance in the underlying design and implementation process.

Hence, one of the main challenges to increasing programmer efficiency and productivity has been the transformation of relational data into objects that can be used seamlessly, in a natural OO programming fashion, for writing the underlying code. This process has required having a good understanding of how to sequence the data access API calls, and having a good technical understanding of the underlying data access programming model (for example, JDBC), in addition to having good coding skills and the ability to break down the software (and in particular its data access layer) into modularized segments.

The project code named pureQuery gives database application developers an easy, GUI-based means to significantly increase productivity in both the design and implementation phases. This is accomplished through user-initiated automatic transformation of relational data into Java objects for access and manipulation of data. In turn, these objects can be seamlessly utilized in a natural OO programming paradigm to write the business logic and the underlying code. pureQuery's functionality in effect eliminates traditional JDBC programming by integrating the query language with Java.

This article provides an overview of pureQuery and includes a step-by-step scenario showing how pureQuery can significantly increase programmer productivity.


pureQuery: What is it?

pureQuery is an Eclipse-based, pluggable component that seamlessly integrates with the Eclipse Integrated Development Environment (IDE). It automatically provides the design and runtime means for managing relational data as objects. The design provides the means for the developer to specify a database connection (using for example DB2®), thus enabling the Eclipse Java project to be aware of the underlying database artifacts (such as tables, stored procedures, and so on). Once the connection and the auto discovery of all database artifacts are completed, users can intuitively, through the GUI , transform any one of the underlying relational table entities into a Java object. This is accomplished through auto generation of the relevant SQL statements and auto creation of the parent Java objects that encapsulate those statements. The generated Java objects and the contained SQL statements can be further customized in a natural Eclipse IDE programming environment with full integrated SQL and Java editing capabilities.

The tight integration of SQL inside the Java editor provides the required programming productivity increase and the same seamless design time experience and ease of use for SQL coding as writing Java code. The editor integration includes fully supported semantic and syntactic validation through design time compilation, content assist, syntax colorization, and dynamic and selective SQL execution inside Java where errors are marked in an identical manner as Java errors in the error pane.

Furthermore the tightly integrated hand shaking that takes place between design and runtime makes it possible to run SQL statements at design time. taking into account any host variables and parameters used, to preview result sets, and to auto-rollback any side effects that the execution of SQL statements may cause.

Additionally performance analysis of selected SQL statements at design time can be performed through the launch of Visual Explain, thus providing the graphical representation of the optimizer implementation of a query request. The query request is broken down into individual components with icons representing each unique component. Visual Explain also includes information on the database objects considered and chosen by the query optimizer. Visual Explain's detailed representation of the query implementation makes it easier to understand where the greatest cost is being incurred, all at design time, from inside the integrated SQL-Eclipse Java editor.

pureQuery objectization process

The pureQuery system provides three distinct ways to auto-transform the relational access layer into an object based model.

  • Database-driven objectization (DDO):
    The most common usage of pureQuery is to select a table and to generate the objects for data access and manipulation, otherwise referred to as CRUD (create, replace, update, delete). This is where pureQuery generates the OO-based classes and interfaces required to perform the CRUD operations on the selected tables. It also generates a special class that can be used to unit test the objects created. In effect this is a Table-to-Java transformation where Java-centric CRUD operations are generated based on the underlying table's characteristics. We will discuss this more in detail in the section A quick tour.
  • Query-driven objectization (QDO):
    It is often the case that the process of building an application originates from having a set of database query statements (i.e. SQL). This is when object hierarchies need to be created based on existing query statements, which in turn can be used to build the underlying application. In effect this is a SQL-to-Java transformation where Query statements are seamlessly converted into Java-centric objects. The pureQuery system, through a simple point-and-click selection of a query statement and in an intuitive GUI manner via a pop-up context menu, can easily be asked to generate the relevant object class hierarchies. The system in essence utilizes the metadata obtained as a result of parsing the query statements (and if applicable through metadata it maintains from its underlying database connection) to auto-generate the required object classes.
  • Object-relational mapping (ORM):
    There are instances when a bean class that is meant to represent a relational table is available, but the actual link between that class and the desired table in the database does not exist. pureQuery provides an intuitive mechanism through its rich content assist infrastructure to perform a one-to-one mapping of the class name to a given table name residing in the underlying database, as well as the ability to map the class's protected (or public) variables to that table's columns. In effect this is a Java-to-SQL transformation where Java-centric entities are seamlessly converted into SQL based CRUD operations.

There are also instances when a given bean class with all the required relational mapping meta-data exists, but the underlying physical tables to which it is mapped are missing. pureQuery provides the intuitive UI means to derive and to generate the required DDL statements from the bean class for the creation of the required underlying database artifacts (that is, tables and columns).


A quick tour

The following sections examine the most common usage of pureQuery through the DDO process, followed by a tour of the QDO and ORM processes as described earlier in the section pureQuery objectization process. Finally an overview of pureQuery's tight integration with the Eclipse Java Editor and the added-value features it offers will be provided. This will include the hand-shaking between the design and runtime for test running of SQL statements.

Before you try the scenarios below, make sure you have installed the following:

  • DB2 for Linux®, UNIX®, and Windows® Version 8.0 or later and the SAMPLE database that comes with the installation
  • Developer Workbench Version 9.5
  • pureQuery plug-in Version 1.0

Links to download DB2 and IBM Viper Developer V9.5 Open Beta (source for the Developer Workbench and the pureQuery plug-in) are located in the Resources section of this article.

A database-driven objectization (DDO) case scenario

In this section, we examine a simple employee personnel scenario where the goal is to programmatically, in an OO paradigm, access and manipulate the employee data.

In the following steps, you create a pureQuery-aware Java project that transforms the Employee table in the DB2 SAMPLE database into an object model that in turn can be used in a natural, object-oriented fashion in any Java application.

The design pattern for the development of database applications using pureQuery consists of the following basic steps:

Step 1. Create a Java Project in the Eclipse IDE

When creating the Java project, make sure the source and bin folders are created. Name the project "Personnel" .

Step 2. Make your Personnel Java project pureQuery enabled

  1. Select with your right mouse button the Personnel Java project and from the menu select Add pureQuery Support.
    Figure 1. pureQuery enable your Eclipse Java project
    pureQuery enable your Eclipse Java Project

    To see a larger version of this file, click here.

    This launches the Add pureQuery Support wizard that you use to enable your Java project for pureQuery.

  2. The first page of the wizard consists of general options. You can leave the default values as they are. Most importantly, make sure the checkbox next to Import required pureQuery JAR files into project is checked. This is because pureQuery has its own specific design and runtime JAR files that must be included with your Java project.
    Figure 2. Add pureQuery Support wizard: pureQuery general option page
    Add pureQuery Support Wizard: pureQuery General Option page

    Click Next to go to the next page of the Add pureQuery Support wizard.

  3. Next you create the database connection. This page displays all discovered database connections. Here you select one from the list. If there are no existing connections, the wizard will guide you to create a new connection. For this example, select the SAMPLE database, where the Employee table resides.
    Figure 3. Add pureQuery Support wizard: pureQuery database connection page
    Add pureQuery Support Wizard: pureQuery Database Connection Page
  4. Click on the Finish button to dismiss the wizard and to pureQuery-enable the Personnel Java project.

Step 3. Transform the relational artifacts into Java objects and auto-generate the pureQuery code

Once the database connection is made, the Java project becomes database aware. This will result in the automatic display of all database artifacts for that particular connection in the Database Explorer tree view of the IDE, as shown in Figure 4.

Figure 4. Database explorer populated with all artifacts from the SAMPLE database
Database explorer populated with all artifacts from the SAMPLE database

To see a larger version of this file, click here.

The power of pureQuery is in its ability to auto-generate the required code in order to transform any one of the underlying relational database table artifacts into Java objects. This is simply done by selecting the desired database artifact and launching the pureQuery Code Generation wizard.

Follow these steps to transform the relational artifacts into Java objects and auto-generate the pureQuery code:

  1. For this example, select the Employee table node from the database explorer tree view, and click the the right mouse button on that node, as shown in Figure 5.
    Figure 5. Transform the Employee table into a Java object: Auto-generate the pureQuery code
    Transform the Employee table into a Java object: Auto-generate the pureQuery code

    To see a larger version of this file, click here.

  2. From the pop-up menu, select the Generate the pureQuery code option. This launches the Generate pureQuery Code wizard, shown in Figure 6.
    Figure 6. pureQuery Code Generation Wizard
    pureQuery Code Generation Wizard
  3. Specify the Java Bean General options.

    The first page of the Generate pureQuery Code for a Table wizard, shown in Figure 6, consists of attributes that are meant to describe a bean class representing the Employee table. You can leave the default values as they are. Lets examine a few of the attributes:

    • Source folder: This field specifies where all the generated java files will physically reside. You can leave the default value as is: Personnel/Src.
    • Name: This field represents the name of the generated Java Bean. By default the name of the bean will be the same as the selected database table artifact in the Database Explorer for which the pureQuery code generation is being requested (in this case being the Employee table). You can change the name and the result would be an annotation in the final generated file to indicate the mapping between the bean and the corresponding database table artifact.

      For this example change the name to be MyEmployee. The generated annotation will then be:

      @Table(name="EMPLOYEE", schema="DB2ADMIN")
    • Generate annotated-method interface for table: This will result in generation of an Interface file containing database Create/Update/Delete/Insert methods. These methods in essence facilitate the Objectization of the database rows as expressed earlier in section 1.0. A default implementation for this interface with all required SQL statements is also generated when the project is built. Note that the default interface name can optionally be changed.
    • Generate test class for annotated-method interface for table: This will result in the generation of a special class that can be used for unit testing of the bean interface. Optionally the test class name can be changed.
    • Generate test class for Inline-method style: This will result in the generation of file that would contain explicit in-line SQL statements that otherwise by default would be generated as methods of the interface implementation. A simplified API provides consistent way to use SQL to query disparate data sources. Applications can be configured to run the database SQL statically without any change in programming or user experience. Optionally the name of the test class can be changed.
    • Note that in both cases above the system can optionally be asked to auto-generate a set of JUnit test instances by selecting Generate JUnit test cases checkbox.
    • Include Connection information and user name: This option will result in the inclusion of connection string and user name in all generated test classes.
  4. Specify how to define the generated bean variables.

    In the second page of the wizard (shown in Figure 7), you can optionally specify whether to generate public or protected fields and with or without public accessor methods.

    Figure 7. pureQuery Code Generation for defining the bean fields
    pureQuery Code Generation for defining the bean fields

    You can also optionally change the name of beans variable names (which by default are set to be the same as the columns of the Employee table). Note that a special annotation is generated for every variable name that is different from its respective mapping column name. The annotation will be of the form:

    @Column(name="name of the table column")

    and is preceded by the variable declaration. For example in this particular case change the name of the Bean field name firstnme to firstnme_new. The annotation that is generated and preceded to the declaration in the java file will be:

    @Column(name="FIRSTNME") protected string firstnme_new

    The same would take place for every other variable name that is different from the table column name (see Figure 9).

    For this example make sure the Protected Fields with Public accessor methods is checked. Optionally you can also change the variable type name to be different than its mapping columns data type.

  5. Specify different flavors of SQL statements to generate.

    In the final page of the wizard (see Figure 8), you can optionally select different flavors of SQL statement(s) to be generated. For this example select Generate all SQL statements.

    Figure 8. Different flavors of SQL statements to be generated
    Different flavors of SQL statements to be generated
  6. Click Finish to generate the pureQuery code.

Upon clicking on the Finish button, the wizard generates a utility package in addition to the following five main files that complete the DDO process as expressed earlier in the section entitled pureQuery objectization process. Let's examine what the generated artifacts include:

  • Files that constitute the object hierarchy
    1. MyEmployee.java (see Figure 9): This is the main bean class. This class contains variables and their respective accessor methods with 1-1 mapping to the Employee table columns.
      Figure 9. Java bean class representing the Employee table
      Java bean class representing the Employee table

      To see a larger version of this file, click here.

    2. MyEmployeeData.java (see Figure 10): This is the interface file that abstracts the database access layer for data query and manipulation. It contains abstract methods whose sole implementation purpose is to perform the CRUD operations on the underlying table.
      Figure 10. MyEmployeeData.java containing the interface for CRUD operations
      MyEmployeeData.java containing the interface for CRUD operations

      To see a larger version of this file, click here.

    3. MyEmployeeDataImpl.java (see Figure 11): This is the default implementation for the MyEmployeeData interface as noted earlier. The implementation contains methods encapsulating all required SQL statements for data access and manipulation.

      Please note: This file is generated if and only if the project is built. This can happen either by setting the Build Automaticallyoption of the Project from the main Eclipse IDE menu, or by the developer manually building the project.

      Figure 11. A class with interface method implementation
      A class with interface method implementation

      To see a larger version of this file, click here.

    4. MyEmployeeDataTest.java (see Figure 12): This is the default class generated by the pureQuery system that can optionally be used for unit testing purposes. It contains a static main function that in essence exercises the running of all methods in the implementation class (namely MyEmployeeDataTest.java).
      Figure 12. This generated class can be used for the purpose of unit testing
      This generated class can be used for the purpose of unit testing

      To see a larger version of this file, click here.

    5. MyEmployeeInLineSample.java (see Figure 13): This file is generated if -- and only if-- the Generate Sample Class With Inline method call syntax option is checked. This in essence exercises the running of all generated SQL statements using the in-line style method call via pureQuery's runtime APIs.
      Figure 13. Auto-generated test class to exercise in-line generated SQL statements
      Auto-generated test class to exercise in-line generated SQL statements

      To see a larger version of this file, click here.

  • Utility Package

    In addition to the files generated in the preceding section, the pureQuery system also generates a utility package consisting of a file called SampleUtil.java (see Figure 14). This file contains a number of generic static utility functions (such as getting connection, print, and so on) that for example are used by the generated test class (namely MyEmployeeDataTest.java) to print the output result and to create the underlying database connection.

    Figure 14. Auto-generated sample class contains a number of generic static utility functions
    Auto-generated sample class contains a number of generic static utility functions

    To see a larger version of this file, click here.


A query-driven objectization (QDO) case scenario

Given one or more SQL statements, pureQuery provides an intuitive means to auto create the object hierarchies for the relational data access layer. The following step-by-step walk through will illustrate the power of pureQuery in creating object models given only the SQL statements.

  1. Open the same Eclipse Java Personnel project as created in the earlier section on the DDO case scenario.
  2. Add a new Java file class to the project and include the following SQL statement in the Main method:
    SELECT BIRTHDATE, BONUS, COMM, EDLEVEL, EMPNO, FIRSTNME, HIREDATE, JOB, LASTNAME, 
    MIDINIT, PHONENO, SALARY, SEX, WORKDEPT from EMPLOYEE
  3. Point and right mouse button click anywhere in the SQL statement, and from the pop-up context menu select the pureQuery Assist -> Generate SQL Bean option. This will result in the launch of Create Bean for a SQL Result Set wizard .
    Figure 15. Create a bean from an SQL statement
    Create a bean from an SQL statement

    To see a larger version of this file, click here.

  4. On the first page specify a name for the Bean class to be generated. In this case enter "MySQLEmployee" and click on the Next button.
    Figure 16. Specify the Bean Class name to be generate from SQL statement
    Specify the Bean Class name to be generate from SQL statement
  5. In the second page of the wizard you can specify how to define the bean fields. For this example you can leave the default values as they are. Optionally you can also change the variable type name to be different than its mapping columns data type (See Figure 17).
    Figure 17. Specify the bean fields
    Specify the bean fields
  6. Click on the Finish button. This will generate the bean file, MySQLEmployee.Java.

To create the interface and the default implementation file, you can use pureQuery's ORM process, shown in the next section.


An object-relational mapping (ORM) case scenario

Given a Java bean class, pureQuery provides an intuitive mechanism to map the members of that class to any given relational entity in the underlying database table.

Note that the design time mapping needs to be done according to the table schema and rules-of-the-game . For example even though at design time a variable of data type double can be mapped to a table column of type XML, the run time consequences are unpredictable and hence resulting in errors. The following walk though example illustrates this mapping.

  1. Open the same Eclipse Java Personnel project as created in the DDO example.
  2. To illustrate the ORM feature, you can either use an existing bean or a Java user-defined class which is the representative of a table in the database. In this example we use an existing bean, so delete all generated Java files except MyEmployee.Java.
    Figure 18. Mapping a bean to a relational table
    Mapping a bean to a relational table

    To see a larger version of this file, click here.

  3. With MyEmployee.Java class opened in the editor, add the following annotation at the top of the class name:
    @Table (name = "EMPLOYEE", Schema = "DB2ADMIN")

    This annotation performs the actual mapping between the class name and the table in the underlying database.

  4. Add the following annotation at the top of every field/variable for which you wish the mapping to take place. In this example we only map BIRTHDAY and FIRSTNME fields, hence add
    @Column (name = "BIRTHDAY")

    at the top of the BIRTHDAY variable name, and
    @Column (name = "FIRSTNME")

    at the top of FIRSTNME variable name (See Figure 19).
    Figure 19. Annotation creates the mapping between host variables and table columns
    Annotation creates the mapping between host variables and table columns

    To see a larger version of this file, click here.

  5. Now point and right mouse button click anywhere inside the MyEmployee class in the editor, and from the pop-up context menu select the pureQuery Assist -> Generate pureQuery CODE option. This will result in the launch of the Generate pureQuery Code for a Table wizard as described earlier, which will ultimately generate the pureQuery related code (including interface files, test classes, implementation code, and so on.).

Note that since the Java bean class already exists, the wizard's Bean Field page is omitted from being presented to the user.


pureQuery's content assist and tight integration with the Java editor

One of the most powerful features that pureQuery offers is the seamless integration between SQL and Java in one single editor. This tight integration provides a consistent set of design time features for both Java and SQL, including code assist, syntax validation, and colorization, in addition to semantic validation of the SQL statements.

Code assist provides:

  • SQL statement completion whereupon typing an SQL keyword such as SELECT, or where an operator is expected, a context window is shown displaying possible ways to complete the statement.
    Figure 20. Statement completion
    Statement Completion

    To see a larger version of this file, click here.

  • Content Assist displays a list of possible entity names associated with a given relational artifact (such as a table, schema, and so on), or list of Java host variables where parameters need to be specified in a statement (see Figures 21 and 22).
    Figure 21. Content Assist
    Content Assist

    To see a larger version of this file, click here.

    Figure 22. Host Variable Content Assist
    Host Variable Content Assist

    To see a larger version of this file, click here.

  • Quick Fix provides an in-line dynamic syntax validation mechanism where errors such as misspelling are detected and quickly fixed .
    Figure 23. Quick Fix: Select key word misspelled as Selct
    Quick Fix: Select key word misspelled as Selct

    To see a larger version of this file, click here.

  • Auto-discovery of database definition (See Figures 24 and 25) provides a quick jump to the database definition in the database explorer through a point-and-click selection of any one of the bean member names (for example, class name which maps to a table name would jump to the table node in the database explorer, variable names mapping to column names would jump to column nodes in the Database explorer, and so on).
    Figure 24. Point-and-click select the member name in the bean class
    Point-and-click select the member name in the bean class

    To see a larger version of this file, click here.

    Figure 25. Point-and-click selection jumps to database explorer
    Point-and-click selection jumps to database explorer

    To see a larger version of this file, click here.


Design and runtime hand-shaking

One of the most advantageous features of pureQuery's design time functionality resides in its ability to dynamically run any given SQL statement from within the editor. This unique feature makes it possible for dynamic execution of SQL statements at design time with rollback capabilities.

To see this feature while in the Java Editor, simply point-and-click with right mouse button down on any one of the generated SQL statements. From the context menu select pureQuery Assist -> Run SQL (see Figure 26). This will execute the SQL statement and the result set will be displayed in the Data View of the Eclipse IDE (see Figure 27).

Figure 26. Point-and-click selection to run the SQL at design time
Point-and-click selection to run the SQL at design time

To see a larger version of this file, click here.

Figure 27. Result of the SQL execution at design time displayed in Data View
Result of the SQL execution at design time displayed in Data View

To see a larger version of this file, click here.


Conclusion

In an era where data and its efficient accessibility are the driving force behind the evolution of database-centric business applications into pure services delivered over the Web (or otherwise), and in the interest of increase productivity for rapid application development and maintenance, the need to have an object-oriented infrastructural framework has never been greater. IBM's pureQuery, through a seamless intuitive objectization process of relational access, provides a state-of-the-art, pluggable solution to the Eclipse IDE environment for optimizing developers' productivity and performance.

Resources

Learn

Get products and technologies

  • Download a free trial version of DB2 Enterprise 9.
  • Now you can use DB2 for free. Download DB2 Express-C, a no-charge version of DB2 Express Edition for the community that offers the same core data features as DB2 Express Edtion and provides a solid base to build and deploy applications.
  • Download the IBM Viper Developer V9.5 Open Beta to obtain the pureQuery plug-in and the version of the DB2 Developer Workbench required for this article.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Information management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Information Management, Java technology
ArticleID=248872
ArticleTitle=Understanding pureQuery, Part 1: pureQuery: IBM's new paradigm for writing Java database applications
publish-date=12142007