Chapter 8. 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 home interfaces and are used for locating entity beans. All home interfaces must have a findByPrimaryKey( ) method, which takes the primary key of the entity bean as an argument and returns a remote or local reference to that entity bean. For example, the Cruise EJB defines this find method in its home interface as:

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

In addition to the mandatory findByPrimaryKey( ) method, home interfaces can define as many custom find methods as needed. For example, the Cruise EJB might define a method called 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;
}

It’s not obvious to the container how a custom find method should behave. In EJB 1.0 and 1.1, vendors came up with their own query languages and methods to specify the behavior of these other solutions. 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. EJB 2.1 enhances EJB QL by adding aggregate functions, the ORDER BY clause, and other new features. The differences in EJB QL between EJB 2.1 and EJB 2.0 are clearly stated throughout this chapter.

EJB QL is a declarative query language 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. 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, the EJB QL statements are translated into data access code optimized for a specific 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 to define queries that are 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 rich and flexible query language that empowers developers, 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, 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 AS 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 a particular find method, 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 is 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. Each element must declare a unique name. These names must be unique: 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.

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

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