EJB QL is a powerful new tool that promises to improve performance, flexibility, and portability of entity beans in container-managed persistence, but it has some design flaws and omissions.
The use of the OBJECT()
operator is unnecessary and
cumbersome and provides little or no value to the bean developer.
It’s trivial for EJB vendors to determine when an abstract
schema type is the return value, so the OBJECT()
operator provides little real value during query translation. In
addition, the OBJECT()
operator is applied
haphazardly. It’s required when the return type is an abstract
schema identifier, but not when a path expression of the
SELECT
clause ends in a CMR field. Both return an
EJB object reference, so the use of OBJECT()
in
one scenario and not the other is illogical and confusing.
When questioned about this, Sun replied that several vendors had
requested the use of the OBJECT()
operator because
it will be included in the next major release of the SQL programming
language. EJB QL was designed to be similar to SQL because SQL is the
query language that is most familiar to developers, but this
doesn’t mean it should include functions and operations that
have no real meaning in Enterprise JavaBeans.
Soon after you begin using EJB QL, you will probably realize that
it’s missing a major component, the
ORDER
BY
clause. Requesting
ordered lists is extremely important in any query language, and most
major query languages, including SQL and object query languages,
support this function. The ORDER
BY
clause has a couple of big advantages:
It provides a clear mechanism for the bean developer to communicate
her intentions to the EJB QL interpreter. The
ORDER
BY
clause is unambiguous;
it states exactly how a collection should be ordered (by which
attributes, ascending or descending, etc.). Given that EJB QL’s
purpose is to clearly describe the behavior of the find and select
operations in a portable fashion, ORDER
BY
is clearly a significant omission.
In most cases, it would allow EJB QL interpreters used by EJB vendors
to choose an ordering mechanism that is optimized for a particular
database. Allowing the resource to perform the ordering is more
efficient than having the container do it after the data is
retrieved.[34] However, even if the application server vendor chooses to
have the container do the ordering, the ORDER
BY
clause still provides the EJB vendor with a
clear indication of how to order the collection. It’s up to the
vendor to choose how to support the ORDER
BY
clause. For databases and other resources that
support it, ordering can be delegated to the resource. For those
resources that don’t support ordering, it can be performed by
container. Without an ORDER
BY
clause, the deployer has to manipulate collections manually or force
the container’s collection implementations to do the ordering.
These two options are untenable in real-world applications in which
performance is critical.
According to Sun, the ORDER
BY
clause was not included in this version of the specification because
of problems dealing with the mismatch in ordering behavior between
the Java language and databases. The example they gave had to do with
string values. The semantics of ordering strings in a database may be
different than those of the Java language. For example, Java orders
String
types according to character sequence and
case (uppercase vs. lowercase). Different databases may or may not
consider case while ordering, or they may not consider leading or
trailing whitespace. In light of these possible differences, it seems
as though Sun has a reasonable argument, but only for limiting the
portability of ORDER
BY
, not
for eliminating its use all together. EJB developers can live with
less than perfect portability of the ORDER
BY
clause, but they cannot live without the
ORDER
BY
clause altogether.
Another argument against using the ORDER
BY
clause is that it necessitates the use of
java.util.List
as a return type. Although the
List
type is supposed to be used for ordered
lists, it also allows developers to place items in a specific
location in the list, which in EJB would mean a specific location in
the database. This is nearly impossible to support, and so appears to
be a reasonable argument against using the ORDER
BY
clause. However, this reasoning is flawed,
because there is nothing preventing EJB from using the simple
Collection
type for ordered queries. The
understanding would be that the items are ordered, but only as long
as the collection is not modified (i.e., elements are not added or
removed after it is obtained). Another option is to require that EJB
QL statements that use the ORDER
BY
clause return a
java.util.Enumeration
type. This seems perfectly
reasonable, since the Collection
received by a
select or find operation shouldn’t be manipulated anyway.
While Sun has not defined EJB QL as supporting the
ORDER
BY
clause, some EJB
servers (such as BEA’s WebLogic) are expected to support it
anyway using nonstandard extensions. This support is both welcome and
problematic, because nonstandard extensions to EJB QL can result in
nonportable enterprise beans.
EJB QL doesn’t provide native support for the
java.util.Date
class. This is not acceptable. The
java.util.Date
class should be supported as a
natural type in EJB QL. It should be possible, for example, to do
comparisons with Date
CMP fields and literal and
input parameters using comparison operators (=, >, >=,
<, <=, <>)
. It should also be possible
to introduce common date functions so that comparisons can be done at
different levels, such as comparing the day of the week
(DOW())
or month (MONTH()
),
etc. Of course, including the Date
as a supported
type in EJB QL is not trivial and problems with interpretation of
dates and locales would need to be considered, but the failure to
address Date
as a supported type is a significant
omission.
While the functional expressions provided by EJB
QL will be valuable to developers, many other functions should also
have been included. For example, COUNT()
is used
often in real-world applications, but it is not currently supported
in EJB QL. Other functions that would be useful include (but are not
limited to) CAST()
(useful for comparing different
types), MAX()
and MIN()
,
SUM()
, and UPPER()
. In
addition, if support for java.util.Date
was
included in EJB QL, other date functions, such as
DOW()
, MONTH()
, etc., could
be
added.
[34] It was suggested that EJB vendors could provide ordering mechanically, by having the collection sorted after it’s obtained. This is a rather ridiculous expectation, since it would require collections to be fully manifested after the query completes, eliminating the advantages of lazy loading.