The Query Methods

There are two main types of query methods: find methods and select methods. These are discussed in the following sections.

Find Methods

Find methods are invoked by EJB clients (applications or beans) to obtain EJB object references to specific entity beans. For example, you might call the findByPrimaryKey( ) method on the Customer EJB’s home interface to obtain a reference to a specific Customer bean.

Find methods are always declared in the local and remote home interfaces of an entity bean. Specifying a single remote or local return type for a find method indicates that the method locates only one bean. findByPrimaryKey( ) obviously returns a single remote reference, because there is a one-to-one correspondence between a primary key’s value and an entity. Other single-entity find methods can also be declared. For example, in the following code segment the Customer EJB declares several single-entity find methods, each of which supports a different query:

public interface CustomerHomeRemote extends javax.ejb.EJBHome {
    public CustomerRemote findByPrimaryKey(Integer primaryKey)
        throws javax.ejb.FinderException, java.rmi.RemoteException;

    public CustomerRemote findByName(String lastName, String firstName)
        throws javax.ejb.FinderException, java.rmi.RemoteException;

    public CustomerRemote findBySSN(String socialSecurityNumber)
        throws javax.ejb.FinderException, java.rmi.RemoteException;
}

Bean developers can also define multi-entity find methods, which return a collection of EJB objects. The following listing shows a couple of multi-entity find methods:

public interface CustomerHomeLocal extends javax.ejb.EJBLocalHome {
    public CustomerLocal findByPrimaryKey(Integer primaryKey)
        throws javax.ejb.FinderException;

    public Collection findByCity(String city,String state)
        throws javax.ejb.FinderException;

    public Collection findByGoodCredit( )
        throws javax.ejb.FinderException;
}

To return several references from a find method, you must use a java.util.Collection type.[22] A find method that uses this return type may have duplicates. To avoid duplicates, use the keyword DISTINCT in the EJB QL statement associated with the find method. Multi-entity finds return an empty Collection if no matching beans are found.

All query methods (find or select) must be declared as throwing the javax.ejb.FinderException . Find methods that return a single remote reference throw a FinderException if an application error occurs and a javax.ejb.ObjectNotFoundException if a matching bean cannot be found. The ObjectNotFoundException is a subtype of FinderException that is thrown only by single-entity find methods.

With the exception of findByPrimaryKey( ) methods, all find methods must be declared in <query> elements in the bean’s deployment descriptor. Query declarations for findByPrimaryKey( ) methods are not necessary and, in fact, are forbidden. It’s obvious what this method should do, and you may not try to change its behavior. The following snippet from the Customer EJB’s deployment descriptor shows declarations of two find methods, findByName( ) and findByGoodCredit( ) :

                  <query>
    <query-method>
        <method-name>findByName</method-name>
        <method-params>
            <method-param>java.lang.String</method-param>
            <method-param>java.lang.String</method-param>
        </method-params>
    </query-method>
    <ejb-ql>
        SELECT OBJECT(c) FROM Customer AS c 
        WHERE c.lastName = ?1 AND c.firstName = ?2
    </ejb-ql>
</query>
                  <query>
    <query-method>
        <method-name>findByGoodCredit</method-name>
        <method-params/>
    </query-method>
    <ejb-ql>
        SELECT OBJECT(c) FROM Customer AS c
        WHERE c.hasGoodCredit = TRUE
    </ejb-ql>
</query>

The <query> elements allow the bean developer to associate EJB QL statements with specific find methods. When the bean is deployed, the container attempts to match the find method declared in each of the query elements with find methods in the entity bean’s home interfaces. To do so, it matches the values of the <method-name> and <method-params> elements with method names and parameter types (ordering is important) in the home interfaces.

When two find methods have the same method name and parameters, the query declaration applies to both methods. (This situation occurs when similar find methods are in the local home and remote home interfaces.) The container returns the proper type for each query method: the remote home returns remote EJB objects, and the local home returns local EJB objects. You can therefore define the behavior of both the local and remote home find methods using a single <query> element, which is convenient if you want local clients to have access to the same find methods as remote clients.

The <ejb-ql> element specifies the EJB QL statement for a specific find method. EJB QL statements can use input parameters (e.g., ?1, ?2, ... ?n), which are mapped to the <method-param> elements of the find method, as well as literals (e.g., TRUE).

Select Methods

Select methods are similar to find methods, but they are more versatile and can be used only internally, by the bean class. In other words, select methods are private query methods; they are not exposed to an entity bean’s interfaces.

Select and find methods also execute in different transaction contexts. The select method executes in the transaction context of the business or callback method that is using it, while the find methods execute according to their own transaction attributes, as specified by the bean provider.

Select methods are declared as abstract methods using the naming convention ejbSelect< METHOD-NAME >. Here are four select methods declared in the AddressBean class:

public class AddressBean implements javax.ejb.EntityBean {
    ...
    public abstract String ejbSelectMostPopularCity( )
        throws FinderException;
    
    public abstract Set ejbSelectZipCodes(String state)
        throws FinderException;

    public abstract Collection ejbSelectAll( )
        throws FinderException;

    public abstract CustomerLocal ejbSelectCustomer(AddressLocal addr)
        throws FinderException;
    ...
}

Select methods can return the values of CMP fields. The ejbSelectMostPopularCity( ) method, for example, returns a single String value, the name of the city referenced by the most Address EJBs.

To return several references from a select method, you must declare the return type to be either a Collection or a Set.[23] Which type to return depends on whether you want to allow duplicate values. By definition, a Set never contains duplicates, while a Collection may have duplicates. Multi-entity selects return an empty Collection or Set if no matching beans are found. For example, the ejbSelectZipCodes( ) method returns a java.util.Set of String values: a unique collection of all the Zip codes declared for the Address EJBs for a specific state.

Like find methods, select methods can declare arguments that limit the scope of the query. For example, the ejbSelectZipCodes( ) and ejbSelectCustomer( ) methods declare arguments that limit the scope of the results. These arguments are used as input parameters in the EJB QL statements assigned to the select methods.

Select methods can return local or remote EJB objects. Whether a single-entity select method returns a local or a remote object is determined by the return type of the ejbSelect( ) method. The ejbSelectCustomer( ) method, for example, returns a local EJB object, the CustomerLocal. This method could easily have been defined to return a remote object by changing the return type to the Customer bean’s remote interface (CustomerRemote). Multi-entity select methods, which return a collection of EJB objects, return local EJB objects by default. However, you can override this behavior by using the <result-type-mapping> element in the select method’s <query> element.

The following snippet from an XML deployment descriptor declares two select methods. Notice that they are exactly the same as the find method declarations:

                  <query>
    <query-method>
      <method-name>ejbSelectZipCodes</method-name>
      <method-params>
      <method-param>java.lang.String</method-param>
      </method-params>
    </query-method>
    <ejb-ql>
        SELECT a.homeAddress.zip FROM Address AS a
                          WHERE a.homeAddress.state = ?1
    </ejb-ql>
</query>
                  <query>
    <query-method>
        <method-name>ejbSelectAll</method-name>
        <method-params/>    
    </query-method>
    <result-type-mapping>Remote</result-type-mapping>
    <ejb-ql>
        SELECT OBJECT(a) FROM Address AS a
    </ejb-ql>
</query>

The name given in each <method-name> element must match one of the ejbSelect< METHOD-NAME >( ) methods defined in the bean class. This is different from find methods in CMP, which use the names of select methods defined by the bean class.

By default, the <result-type-mapping> element in the value of <result-type-mapping> can be either Remote or Local. Local indicates that the select method should return local EJB objects; Remote indicates remote EJB objects. For a single-entity select, the actual return type of the ejbSelect( ) method must match the <result-type-mapping>. In the previous example, the <result-type-mapping> element for the ejbSelectAll( ) method is declared as Remote, which means the query should return remote EJB object types (i.e., remote references to the Address EJB).[24]

Select methods can be used to query all the entity beans declared in the same deployment descriptor. Select methods may be called by a bean’s ejbHome( ) methods, by any business methods, or by the ejbLoad( ) and ejbStore( ) methods. In most cases, select methods will be called by ejbHome( ) or by business methods in the bean class.

The most important thing to remember about select methods is that while they can do anything find methods can and more, they can be used only by the entity bean class that declares them, not by the entity bean’s clients.



[22] In The java.util.Collection is the only collection type supported for multi-entity find methods in CMP.

[23] Other collection types, such as java.util.List and java.util.Map, may be added in future versions.

[24] This is illustrative. As a developer, it is unlikely (although possible) that you would define a remote interface for the Address EJB, because it is too fine-grained for use by remote clients.

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

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