Chapter 8. EJB 2.0 CMP: EJB QL

Find methods have been a part of the Enterprise JavaBeans specification since EJB 1.0. These methods are defined on the entity bean’s local and remote home interfaces and are used for locating entity beans. All entity beans must have a findByPrimaryKey() method, which takes the primary key of the entity bean as an argument and returns a reference to an entity bean. For example, the Cruise EJB defines the standard primary key find method in its home interface as follows:

public CruiseHomeLocal extends javax.ejb.EJBLocalHome 
{
    public Integer create(String name,ShipLocal ship);
    
    public CruiseLocal findByPrimaryKey(Integer key);

}

In addition to the mandatory findByPrimaryKey() method, entity bean developers may define as many custom find methods as they like. For example, the Cruise EJB might define a method, such as findByName(), for locating a Cruise with a specific name:

public CruiseHomeLocal extends javax.ejb.EJBLocalHome 
{
    public Integer create(String name,ShipLocal ship)
        throws CreateException;
    
    public CruiseLocal findByPrimaryKey(Integer key)
        throws FinderException;

    public CruiseLocal findByName(String cruiseName)
        throws FinderException;
}

The option of defining custom find methods is nothing new, but until EJB 2.0 there was no standard way of defining how the find methods should work. The behavior of the findByPrimaryKey() method is obvious: find the entity bean with the same primary key. However, the behavior of custom find methods is not always obvious, so additional information is needed to tell the container how these methods should behave. EJB 1.1 didn’t provide any standard mechanism for declaring the behavior of custom find methods, so vendors came up with their own query languages and methods. Consequently, the custom methods generally were not portable, and guesswork was required on the part of the deployer to determine how to properly execute queries against them. EJB 2.0 introduced the Enterprise JavaBeans Query Language (EJB QL)—a standard query language for declaring the behavior of custom find methods—and the new select methods. Select methods are similar to find methods, but they are more flexible and are visible to the bean class only. Find and select methods are collectively referred to as query methods in EJB 2.0.

EJB QL is a declarative query language that is similar to the Structured Query Language (SQL) used in relational databases, but it is tailored to work with the abstract persistence schema of entity beans in EJB 2.0.

EJB QL queries are defined in terms of the abstract persistence schema of entity beans and not the underlying data store, so they are portable across databases and data schemas. When an entity bean’s abstract bean class is deployed by the container, the EJB QL statements are typically examined and translated into data access code optimized for that container’s data store. At runtime, query methods defined in EJB QL usually execute in the native language of the underlying data store. For example, a container that uses a relational database for persistence might translate EJB QL statements into standard SQL 92, while an object-database container might translate the same EJB QL statements into an object query language.

EJB QL makes it possible for bean developers to describe the behavior of query methods in an abstract fashion, making queries portable across databases and EJB vendors. The EJB QL language is easy for developers to learn, yet precise enough to be interpreted into native database code. It is a fairly rich and flexible query language that empowers developers at development time, while executing in fast native code at runtime. However, EJB QL is not a silver bullet and is not without its problems, as we’ll see later in this chapter.

Declaring EJB QL

EJB QL statements are declared in <query> elements in an entity bean’s deployment descriptor. In the following listing, you can see that the findByName() method defined in the Cruise bean’s local home interface has its own query element and EJB QL statement:

<ejb-jar>
    <enterprise-beans>
        <entity>
            <ejb-name>CruiseEJB</ejb-name>
            ...
            <reentrant>False</reentrant>
            <abstract-schema-name>Cruise</abstract-schema-name>
            <cmp-version>2.x</cmp-version>
            <cmp-field>
                   <field-name>name</field-name>
            </cmp-field>
            <primkey-field>id</primkey-field>
            <query>
                <query-method>
                    <method-name>findByName</method-name>
                    <method-params>
                        <method-param>java.lang.String</method-param>
                    </method-params>
                </query-method>
                <ejb-ql>
                    SELECT OBJECT(c) FROM Cruise c WHERE c.name = ?1
                </ejb-ql>
            </query>
        </entity>
    </enterprise-beans>
</ejb-jar>

The <query> element contains two primary elements. The <query-method> element identifies the find method of the remote and/or local home interfaces, and the <ejb-ql> element declares the EJB QL statement. The <query> element binds the EJB QL statement to the proper find method. Don’t worry too much about the EJB QL statement just yet; we’ll cover that in detail starting in the next section.

Every entity bean that will be referenced in an EJB QL statement must have a special designator called an abstract schema name , which is declared by the <abstract-schema-name> element. The <abstract-schema-name> elements must have unique names; no two entity beans may have the same abstract schema name. In the entity element that describes the Cruise EJB, the abstract schema name is declared as Cruise. The <ejb-ql> element contains an EJB QL statement that uses this identifier in its FROM clause.

In Chapter 7, you learned that the abstract persistence schema of an entity bean is defined by its <cmp-field> and <cmr-field> elements. The abstract schema name is also an important part of the abstract persistence schema. EJB QL statements are always expressed in terms of the abstract persistence schemas of entity beans. EJB QL uses the abstract schema names to identify entity bean types, the container-managed persistence (CMP) fields to identify specific entity bean data, and the container-managed relationship (CMR) fields to create paths for navigating between entity beans.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset