Umit and Linda, I'd very much like your input on this.
This week I've been working on an article regarding workarounds
for queries not expressible in EJB-QL, and to my dismay the
situation now appears even graver than before. Before I draw
any conclusions, I'd very much like to check my facts.
(Issue 1) There very basic queries that simply cannot be
expressed in EJB-QL.
Consider the following following e-commerce example taken from
the spec (figure 34 on pg 221). You've got an order with
many line items (as shown in figure 34 on pg 221 of the EJB
2.0 spec).
Queries involving AT LEAST ONCE semantics for multi-valued
relationship are easy.
Objective: Retrieve all of Judy's orders which have AT LEAST ONE
unshipped line item
EJB-QL: SELECT DISTINCT OBJECT(o)
FROM Order AS o, IN(o.lineItems) AS l WHERE o.name =
'Judy' AND l.shipped = FALSE
This works great. But consider queries with FOR ALL semantics:
Objective: Retrieve all of Judy's orders where ALL line items
are shipped.
Based on my understanding of chapter 11 of the spec, that
query simply cannot be done using EJB-QL! For if I were to try:
EJB-QL: SELECT DISTINCT OBJECT(o)
FROM Order AS o, IN(o.lineItems) AS l WHERE o.name =
'Judy' AND l.shipped = TRUE
I'd get back all orders where AT LEAST ONE line item is shipped,
rather than where ALL line items are shipped.
What I'd really want to do is use something like: SELECT
OBJECT(o) FROM Order o WHERE o.li[ANY].shipped = TRUE SELECT
OBJECT(o) FROM Order o WHERE o.li[ALL].shipped = TRUE
In SQL for all semantics are accomplished using nested queries.
But EJB-QL doesn't support nested queries.
(ISSUE 2) Using an SQL query to produce a list of primary keys
for loading breaks bulk loading performance improvements of
CMP 2.0.
Explanation.
Given the need for the query above which can't be done in
EJB-QL, the developer is forced do the Query in SQL. We've got
several choices here: (a) Use BMP instead of CMP. (b) Use
CMP and load the entity beans via home.findByPrimaryKey().
(c) Use CMP and bulk load the entity beans via
home.findByPrimaryKeyCollection(keys).
(d) Don't use entity beans.
Options (a) and (b) suffer from very sever performance
limitations as bulk loading the Entity Beans isn't an
option... 101 database round trips would be required to load
100 entity beans.
Option (c) is a nice option, but it can't be done. EJB-QL is
even to limited for this very simple query to work.
What we'd like to use is something like this:
SELECT OBJECT(o) FROM Order AS o WHERE o.Id IN (?1)
But the EJB-QL BNF (EJB 2.0 Spec section 11.4) doesn't allow
an input variable to be used inside a WHERE clause IN tag.
Rather, the strings inside the IN tag MUST be hard coded
literals... what good is that?
Or we'd like to use something like this:
SELECT OBJECT(o) FROM Order AS o WHERE o.Id MEMBER OF (?1)
But the EJB-QL BNF (EJB 2.0 Spec section 11.4) doesn't allow
an input variable to be used inside a MEMBER OF tag either!
home.findByPrimaryKeyCollection(keys) has the potential to
be a very powerful bulk loading pattern to solve all sorts of
problems, but EJB-QL just doesn't allow it.
So that leaves us with Option (d), DON'T USE ENTITY BEANS!?
No wonder so many people are scared .NET going to eat away at
Java's market share.
Doug Bateman
Senior. Architect & Trainer for The Middleware Company
http://www.middleware-company.com/
http://www.theserverside.com/
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".