The EJB Query Language (EJB-QL)
Part -1
In this article, we will fully understand the syntax and semantics of the EJB Query Language (EJB-QL), which is the language that you use to describe query methods for container-managed persistent entity beans.
Overview
EJB-QL is a standard and portable language for expressing container-managed persistent entity bean query operations. These entity bean query operations can include finder methods (used by external entity bean clients), as well as select methods (used internally by the entity bean itself). EJB-QL is not necessary for bean-managed persistence because the bean provider writes the database access code, which is integrated into the entity bean class itself.
EJB-QL is a new addition to EJB 2.0. Before EJB 2.0, you would need to explain to the container how to implement your query operations in a proprietary way.
For example, you might bundle a container-specific flat-file with your bean. This flat-file would not be portable to other containers, which is very annoying for bean-providers who wish to write components that are container-agnostic.
Throughout this appendix, we will use an E-Commerce object model to illustrate EJB-QL, using such entity beans as orders, line-items, products, and customers. We designed that object model in Chapter X.
A simple example
Let's kick things off with a simple EJB-QL example. Take the following entity bean remote finder method:
public java.util.Collection findAvailableProducts() throws FinderException, RemoteException;
This finder method means to find all products that are currently in-stock.
The following EJB-QL in the deployment descriptor will instruct the container on how to generate the database access code that corresponds to this finder method:
...
...more container-managed persistent fields...
0]]>
...
In the code above, we are putting together a query that resembles SQL or ORQL (see Chapter X for more on OQL). We can refer to entity beans inside of the EJB-QL by using that entity bean's abstract-schema-name defined earlier in the deployment descriptor. We can also query its container-managed fields or container-managed relationships, or other entity beans.
In fact, if we're using a relational database, the container will translate this EJB-QL code into SQL code in the form of JDBC statements.
The following SQL is an example of what might be generated depending on your container implementation:
SELECT DISTINCT p.PKEY
FROM PRODUCT p
WHERE p.INVENTORY > 0
The above SQL returns primary keys (not rows) back to the container. The container than wraps those primary keys in EJB objects and returns RMI-IIOP stubs to the client who called the finder method. When the client calls business methods on those stubs, the EJB objects will intercept the call, and then the ejbLoad() method will be called on the entity beans.
The container will then load the actual rows from the database. Note that this process may be optimized depending on your container implementation.
The power of relationships
The big difference between EJB-QL and SQL is that EJB-QL allows you to traverse relationships between entity beans using a dot-notation. For example:
SELECT o.customer
FROM Order o
In the above EJB-QL, we are returning all customers that have placed orders. We are navigating from the order entity bean to the customer entity bean easily using a dot-notation. This is quite seamless.
What's exciting about this notation is that bean providers don't need to know about tables or columns, rather they merely need to understand the relationships between the entity beans that they've authored. The container will handle the traversal of relationships for us because we declare our entity beans in the same deployment descriptor and ejb-jar file, empowering the container to manage all of our beans and thus understand their relationships.
In fact, you can traverse more than one relationship. That relationship can involve container-managed relationship fields and container-managed persistent fields. For example:
SELECT o.customer.address.homePhoneNumber
FROM Order o
The restriction on this type of recursive relationship traversal is that you are limited by the navigatability of the relationships that you define in the deployment descriptor. For example, let's say that in the deployment descriptor, you declare that orders have a 1-to-many relationship with line-items, but you do not define the reverse many-to-1 relationship that line-items have with orders. When performing EJB-QL, you can then get from orders to line-items, but not from line-items to orders. For more about how to define these types of relationships, see Chapter X in next article.
No comments:
Post a Comment