Hey

Some of you might have seen the latest issue of ObjectWatch issue 20, in
which Roger Sessions makes a lengthy evaluation of the EJB1.1
specification. My evaluation of his critique follow below.

As I will only quote snippets there is a chance that some vital context
is lost. For completeness you should read the whole critique yourself
at:
www.objectwatch.com/issue20.htm
www.objectwatch.com/issue20a.htm
www.objectwatch.com/issue20b.htm
www.objectwatch.com/issue20c.htm
www.objectwatch.com/issue20d.htm (this has not been released yet)

All comments are IMHO, AFAIK, FWIW, etc.

Note: this is an *extremely* long post. Normally I wouldn't be this
talkative, but since this is part of a book that lots of people are
gonna read and (*shudder*) believe I feel that it is of vital importance
that the content is scrutinized closely.

As always, second opinions are important. In issue20b mr Sessions says
that Anne Thomas will be posting a rebuttal article (similar to this I'd
presume). Read that too and see if I have a clue or not.

Ok, let's go!

Part 1 of 5 of the article

"Any so-called persistent object can be implemented as either bean type.
In fact, as I will discuss in this chapter,
most persistent objects would be better off implemented as a session
bean. The real difference between these bean types is how you will
manage the database ID for that persistent
object. For entity beans, the system will manage the database ID for
you. For session beans, you are responsible for managing the database ID
yourself. "

IMHO this is the age-old "assembler vs. OO"-argument: "any program you
can do in Java with OO I can do just as well in assembler". Sure, but it
is a matter of using the right tool for the job, specifically one wants
to minimize the effort needed to implement application X. Assembler is
good for some things and Java/OO for others. Since EntityBeans where
designed with a specific use in mind, why not use them for that?

The definition of EntityBean and SessionBean is not really from the
client perspective but from the bean developer perspective. If a bean
developer needs to choose which type of bean he should use to solve a
specific problem the definition given in the EJB spec. is useful.

He then proceeds to describe how a bean developer might implement a
Customer (the usual stuff: getName, getAddrress, but also
getCreditLimit(??)):
"Should Bernice make Customer a session bean or an entity bean? It's
hard to say. Maybe Customer is an entity bean. Based on its update and
retrieval functionality, and the
specification's admonition that an entity bean is "an object view of
transactional data in the database," the entity choice would be logical.
Customer is also "long-lived;" we don't expect
to lose the customer when the client program goes away. But on the other
hand, credit limit calculations do not represent any direct view of data
in the database, so maybe we are
dealing with a session bean. And this functionality seems to "execute on
behalf of a single client," whatever that means."

The above problem has nothing to do with EJB, but rather that his
OO-"design" is bad. Typically when designing systems such as this one
would try to use the metaphor of a reallife bank. When was the last time
you asked a customer "so, what is your credit limit?". Duh. The given
problem warrants the introduction of Accounts and Tellers, as one would
expect to find in a real bank. Then, it would be simple to ask a Teller:
"Given this Customers Accounts, can you tell me his credit limit?".
Customer is an Entity, Account is an Entity and Teller is a Session.

He then starts to explain about EJB homes:
"Bernice starts implementing Customer as an entity bean. She first thing
she does is create the Enterprise Bean's home interface. A home is a
special type of component, a kind of
finder/creator component, that knows how to create and/or find an
instance of the bean we care about, a Customer in Bernice's case."

and continues with

"Notice that I am using slightly different language than I have used in
previous chapter. I'm trying to use the terminology of EJB, so it won't
be too confusing for those of you in the home
audience trying to follow along with your own EJB specification."

Anyone who has read the EJB specification, or been in this list long
enough, would be somewhat confused with the first statement that a home
is a special type of component. It is not a component. It is something
which is associated with a component, hence his desire to use EJB lingo
has already failed.

Next paragraph:
"Back to our home bean story. Each bean type has one and only one home
in each component process. Component processes, by the way, are referred
to as containers in EJB lingo.
Strictly speaking, a container could be something other than a component
process, but this is unlikely in many EJB implementations. So in EJB
lingo, each container has a Customer
home object."

Anyone familiar with operating systems theory has a pretty good idea of
what a process is, and a EJB-container will not fit that description
very well. An EJB-container is nothing more than a (really) advanced
part of a server, which is a program. A server can contain several
EJB-containers. An executing program is a process. To claim that each
component has its own process is not correct. Also, the statement that
each container has *a* Customer home object is incorrect. A container
can contain one *or more* beans(/homes) as illustrated in EJB1.1 spec.
section 5.2.2.

"The rules for creating a CustomerHome interface say that it must be
derived from the EJBHome interface, which is provided as part of the
Java platform."
Strictly speaking this is not correct. Since EJB is a Java2 extension
the EJBHome interface is not part of the Java platform. It is part of
the Java2 Enterprise Edition platform however. (ok, it's a minor point,
but anyway..)

"She must
define one or more create methods and she must define one or more find
methods."
Again, strictly speaking this is not correct. There is no *need* to
implement create methods. They are optional. Details, dude...

Next sentence:
"The create methods are used for creating a Customer bean and the find
methods are used for finding
an existing Customer bean."
Here he diverges from his above claim to use EJB lingo. In EJB lingo
this would be "..creating a Customer object..". The terms used in EJB1.0
was somewhat confusing as the term "bean" could refer to "instance of
bean class", "the bean component" (as a whole), "the EJBObject", and
lastly (what Sessions is referring to) "an object with an identity".
This has been clarified in EJB1.1.

So to clean up the next paragraph:
"The create methods are actually misnamed. They are not used for
creating the Customer bean, rather they are used for initializing an
already created bean. The bean will be created
using a default constructor on the CustomerBean class."
Yes and no: create methods are for creating Entity objects, not
instances, but Customer objects are indeed "created". The server will
call the default constructor to create CustomerBean class *instances*.
In EJB lingo one would stay as far away as possible from the term
"bean".

And he goes on to say that:
"Once Bernice has created the CustomerHome interface and generated the
ABCCustomerHome class using the ABC code generator, she is ready for the
next step: defining the
Customer interface. In our case, Bernice will define four methods in
this interface. One of these will be the retrieve method, which returns
the information related to a customer. One of
these will be the update method, which is used to change information
related to a customer. One of these will be the credit limit method,
which is used to find out how much more
money we can sucker out of our customer before our system starts
worrying about whether or not that customer can actually pay. And
finally one of these will be the default
constructor, which is used to actually instantiate a Customer."
Actually, he was almost home free here. Disregarding his crappy
OO-design it is "possible" to have retrieve and update methods, and also
a credit limit method, but interfaces cannot have default constructors.
Nope, no way. And this aint no EJB thing, this is a Java thing.

"The rules for creating a Customer Interface tell Bernice she must
derive it from the EJBObject Interface, which is itself derived from
java.rmi.Remote. It is this last derivation that defines
for Java RMI an interface that can be treated as a remote component.
Once Bernice has defined the Customer Interface, she does something
quite remarkable. She doesn't have to
implement any of the methods! Not only was the ABC code generator smart
enough to automatically generate code for the ABCCustomerHome object, it
can also automatically
implement all the code for the actual Customer object to whom Curly's
reference will eventually be speaking. This automatic code generator may
seem more and more unbelievable, but
we shall soon see exactly what the code generator has up its sleeves.
The overall inheritance relationship between the different Customer
related interfaces (and the methods they
define) and classes (and the methods they implement) are shown in Figure
3."

Yes and no: Bernice doesn't have to create the proxy that implements the
Customer interface, *BUUUUUT* she most certainly will have to provide
the implementation that actually does what the methods are supposed to
do on the object. He here wants the reader to think that (in EJB lingo)
the code generator implements the CustomerBean, which it obviously will
not do.

"Poor Bernice. Just when she thought she was getting off easy with the
ABC code generator, she gets to the last step (implementing the
CustomerBean) and she finds that all the hard
work has been left for her."

Ehm.. out of curiosity.. in COM, is it only necessary to define the
interface of a component, or do you actually have to implement the
functionality of the component?

(Divine voice from out of the blue: "Yes you have to implement what you
want to happen")

You have to do that in COM as well? Ok, so why is it that we should feel
sorry for "poor" Bernice here? Uhm.. yeah...

Just checking...

Ok, on with the show. He sums it up with a list of required steps:
"Define the Customer interface.
     Define the CustomerHome interface.
     Include in the above interface at least one create method and at
least one find method.
     Generate the ABCCustomerHome class.
     Implement the CustomerBean class (this is where all the real work
comes in).
     Generate the ABCCustomerBean class.
     Implement the CustomerKey class."
* You don't *have to* make create methods
* You don't *have to* generate classes. Easy-to-use containers will
create these on the fly when the bean is deployed, or some might have
generic implementations that can handle all beans...I mean all
EJB-components
* You don't *have to* implement a CustomerKey class. This was one of the
new (and really good) features in EJB1.1
Makes you wonder if he has ever read the EJB1.1-specification...

A little note on internationalization:
"Commerce systems and databases go together like peanut butter and
jelly."
As a non-US citizen I have no idea if this is good or bad. Is this book
only intended for US readers? Somewhat limited then IMHO.

On CMP:
"This works
great if Bernice isn't too fussy about how or where her Customer's data
is being stored. In most real life situations, Bernice will care a lot,
and will probably have data storage
requirements that exceed the ability of these tools to cope. She will
have specific databases she must use and specific, and often complex,
data formats she must follow to maintain
compatibility with non-JB applications (yes, I know it's hard to
believe, but there still are some non EJB applications around!). So the
usefulness of container managed persistence is
limited to a few rare situations, at least until these tools improve."
The last sentence is extremely important. This limitation has *nothing*
to do with EJB1.1, and since its EJB1.1 we're talking about it's
completely irrelevant. If he wants to put this remark in an evaluattion
of an EJB-server, fine, but this aint the case here.

This kind of confusion between design and implementation is something
that most COM-people seem to have, and they seem to do the same mistake
over and over again... when will they ever learn...

"Client side find requests will be sent through to the EJBFind method
which is also in CustomerBean. The parameter to this method
takes a primary key from the client."
The correct name is ejbFindByPrimaryKey.

On finder return values:
"Curly the client asked the
CustomerHome object to create the Customer bean. He must have, or he
couldn't now be finding it. When he did that, the create method returned
the primary key of the newly created
object."
Wrong. The create method, from Curly the clients perspective, returns a
EJBObject reference.

Ok, moving on to part 3 of 5 in his article.

EJB lingo again:
"And once he has found the home object, he can use it to either create
or find entity components, such as a Customer."
Now he says that home objects are for finding and creating entity
*components*. Again, the correct term is Entity object, as defined and
used in the EJB1.1 specification.

Names, names, names...:
"Where is the point of interception in EJB? It is in the
ABCRemoteCustomer class, the one to which Curly's reference naively
points."
Curiously enough Sessions have never mentioned the ABCRemoteCustomer
class before. OTOH he has has mentioned the ABCCustomerBean class
however, which is what he really means.

"But what happens between when the ABCRemoteCustomer gets
the request from Curly and passes it on to the CustomerBean is entirely
up to the container."

This is not entirely true, of course. The container must follow the
semantic rules for method invocation as defined in the
EJB1.1-specification. This is what it's all about: having rules that we
as bean developers and users know that the component server environment
will follow. The container is in complete charge of the implementation,
but not the semantics.

He then talks a bit about COM:
"Not having database access code anyplace is not an option; it must be
there and it must be there in such a way that its
usage is coordinated with the overall transaction boundaries (as
discussed in Chapter 4, "COMWare")."

Well, I got news for you: in EJB there is no need to have any database
access code at all. And this is one of the core reasons to use EJB:
since there's no need to do db access there's no place to mess things
up, and db access is (in my experience) one of the most error-prone
things one can program. So many things to do wrong, can only mean that
in the end it *will* go wrong. Since we don't have to bother with that
in EJB, we're off the hook.

This it completely confused:
"It is possible to tell an EJB EntityBean that its database ID has
changed. You can do that by changing its EntityContext. And in fact,
this happens quite regularly in EJB as a natural side
effect of the instance management algorithms. But only the container is
allowed to reset an EntityContext; this is not an option available to
clients. The client doesn't even have access to
the EntityContext. The client model is that once a database ID has been
associated with a bean, it can't be changed."

What Sessions have not seemed to grasp is that we are in a world of
objects, not data. The client requests objects, which are named with
primary keys. If an object changes key it is essentially not the same
object. In EJB we use instance pooling to fake this, because allowing
all objects to have one physical instance each is not practical. It's
the same reason as for having database connection pooling really. It is
a known fact that if all clients have their own database connections the
database server breaks down pretty fast. The same thing goes with entity
objects.

He then explains the steps required to access entities:
"The potential problem with all this is that the creation of a reference
to an entity bean is a very time consuming operation in EJB. It requires
the following:

   1.A call to find a remote name context to the Java Naming and
Directory Interface (JNDI).
   2.A remote method call to that name context to find the Home object
and get a reference to it.
   3.A distributed method call to the Home object to get a reference to
the bean.
   4.A search in the database to find the appropriate object data and
load the data, requiring a transaction.

Step 4 is by far the most expensive of all of these, because it requires
a database search and a transaction.
"
1 and 2 are typically done once. Once you have the Home you can keep it
and use it as many times as you wish. 4 is expensive, but then this is
why most advanced EJB implementation uses caching for this: if an entity
object corresponding to a particular primary key is already loaded the
database wont be accessed *at all*. Yes! In the best case the database
is never accessed at all, and *that* is a performance boost that COM can
never have.

Oh, and I just realized: 4 is typically never done. His use case is to
acquire a *reference* to an entity object.. hehe.. well, just acquiring
a reference to an entity object does not require that its data is
actually loaded and activated in a live instance. The cost comes when
you start *using* the reference. Very very very important difference.

The above point totally invalidates the next three paragraphs where he
whines about how costly it is to acquire entity references. Disregard
them completely.

"Oddly enough, even though the EJBSessionEntity does not support
getPrimaryKey, the ABCRemoteCustomer object, the object to which Curly
the client's reference points, does
support getPrimaryKey. How can this be? Simple. If Curly invokes
getPrimaryKey on a session bean, it returns an exception. It is unclear
why the ABCRemoteCustomer's derivation
pattern (as shown in Figure 3) doesn't parallel the derivation pattern
of the CustomerBean (as shown in Figure 4) which would have solved this
problem. Perhaps this is one of the
problems some future release of the specification will fix."

The reason for having one EJBObject interface which contains
getPrimaryKey and throws exception for Sessions has been discussed
extensively on this list. The reaon is simplicity. Three interfaces
(EJBObject, EntityEJBObject (containing only getPrimaryKey) and
SessionEJBObject (containing nothing)) would perhaps make sense as
Sessions notes, but it is way overkill.

On Customer as a SessionBean:
"The getCustomerInformation method needs to read the customer's
information from the database, and to do so, it must have a primary key
for that customer. How will it get it? Since it
isn't available any other way, Bernice must design the method so that it
accepts another parameter, which is the database ID.

The updateCustomerInformation method needs to update the customer's
information in the database, and to do so, it also must have a primary
key for that customer. How will it get it?
The same way the getCustomerInformation method got it, through a
parameter.

The checkCreditLimit method needs to find all kinds of records in the
database related to that customer. It also needs a database key. Are we
seeing a pattern here? Where is it going
to get that key? THROUGH A PARAMETER."
Is it just me, or isn't it kinda awkward to have that parameter fly back
and forth all the time. In his thinking this is good it seems. Ehm..
yeah...right...

On state:
"There is a variant on the session bean that is called a stateful
session bean. This is a misnomer, since the Customer session bean I have
just been discussing is also stateful, it's just that its
state is stored in a database, as you would expect from any self
respecting commerce component."

No, it's not stateful, it's just the OO-design that is so bad that you
think that it is stateful. If I instead had a Teller component to do the
credit checking, would he be stateful? No, because any Teller in a bank
could be replaced with any other Teller in the bank, hence the Teller
does not have any important state which is needed to complete a given
task. What if I gave the Teller a list of tasks to perform, and wanted
to check back later how he was doing? Then it would implement Teller as
a stateful session bean. As simple as that.

And we're now off to part 4 of the article.

Entity references revisited:
"Which of these is better? Most EJB folks would recommend the former, as
the customer seems to fit the general notion of a bean that will outlast
the client's process. But the entity
implementation has a problem. It is much less efficient than the session
implementation. This is because the cost of the reference creation is
much higher for the entity bean than for the
session bean. The reason it is higher is because it, unlike the session
reference creation, requires a database lookup. It requires a database
lookup to make sure the "find" has actually
"found" an existing customer. There is no way to tell this without going
to the database."

Again, the reference creation is not an issue. He does have a point when
he says that "It requires a database lookup to make sure the "find" has
actually "found" an existing customer.". This is almost true. If the
instance is already alive the server wont access the database, it will
instead simply return a reference to the live instance. However, if it
is not alive the server would have to ask the database.

The real issue is that when you then start using the entity object it
will have to be loaded from the database, i.e. there are two database
accesses:
* find it
* load it
But here comes two vital implementation details: databases typically
caches the data, so the overhead of the last call will be minimal if the
time between them is low, and it is also possible for a server to
retrieve the data during the find, cache it internally and then reuse it
when the load request comes. I.e., in real-life this will not be a big
problem. As always, remember that "Cache is king" :-)

On data integrity:
"If we try to avoid the second lookup, we risk the transactional
integrity of the bean; someone else might have come in
and changed the bean's data since we did the find. "
This is only true if the statements are not performed in a transaction.
If it is then the EJB-server will typically block any other client
trying to access it until the transaction has finished. This is what
transactions all are about. If you want transactions, use them.

Additionally:
"As I discussed back in Chapter 4, all COMWare, including EJB, requires
that transactional boundaries be the same as method
boundaries. This means the bean's data has no protection between the
find and the display. The display must therefore reread the data from
the database."
*IF* the code is not performed in a transaction *OF COURSE*, but that's
the whole point of transactions, innit? If you need data integrity
between the two calls then use a *TRANSACTION*.

And to make this even worse his code example is as follows:
"customer = CustomerHome.find("1234");
display (customer.limit());"
As you can see he is not reliant on the data integrity between the two
calls so even if the data is actually changed between the two calls, SO
WHAT? Since any changes done by any other client will be made to the
same live physical instance in main memory (typically at least. There
are other scenarios, but the end result is the same) it will simply
display the latest known limit of the customers credit. No problemo.

And the following example remark:
"The cost for the entity reference is now much more expensive than the
session reference. Not only is the cost of the first reference higher
(as it was in the pattern one usage), but we
must create three times as many references to do the same job."
.. is incorrect. Since his discussion of the reference acquisition costs
are inaccurate, the foundation for this remark is invalid. However, it
is not entirely without merit. If all customer have to be found, loaded
and subsequently stored this might cause nine separate calls to the
database in a worst case scenario. However, if deployed well, and with a
clever server implementation and some luck it requires *0* (zero, zip,
nil) database calls for the entire example. (I wont detail how this is
possible, just take my word for it, ok).

And now he wants to finish off with a example to show how pathetic
EntityBeans are and how good stateless is, and comments it with:
"For this pattern, the initialization costs for the session bean is
actually higher than for the entity bean since it includes the customer
reference creation as well as the Customer home
reference creation. But initialization costs are usually not important
in this type of scenario. Initialization occurs very infrequently. The
much more important cost is the cost of executing
the main body, which happens over and over, perhaps thousands of times
for every one initialization. The main body using the session bean will
execute much faster than the main body
using the entity bean. The session code completely eliminates the cost
of the reference creation."

First he contradicts himself with "initialization costs are usually not
important in this type of scenario" and "...much faster than the main
body
using the entity bean. The session code completely eliminates the cost
of the reference creation". Hello???? Houston calling, R U still there!?

In reality: for sessions, each main body call requires that the code
accesses the database through JDBC. This is typically expensive, but a
clever database will have optimizied this somewhat if the primary key
"1234" is used all the time (caching, caching and caching). For
entities, after the first call the entity object will be loaded and
happy in main memory so all subsequent calls does not require the server
to go to the database. And it wont become stale if EJB is the only way
to interact with the database (which will be the most common scenario
IRL, or otherwise much of the gains with using EJB, or any
componenttechnology are kinda lost).

He then makes a summary and evaluation of the scenario, which is based
on his completely f*d up view of how things work. Comletely disregard
those paragraphs.

And finishes off with:
"Given this analysis, I make the following claim. While entity beans may
seem to offer a more attractive programming model in some scenarios,
that aesthetic advantage is more than
outweighed by performance considerations. Given the increasing
importance of thin (pattern three) clients, for whom entity beans do the
absolute worse, it is difficult to imagine that
anybody will implement any business logic using this inefficient
model.."
Given the above description of why mr Sessions is completely wrong I
would advise you to disregard this remark.

Finally, he makes a lame attempt at being funny, and also explains that
there are five bean types:
"Notice something strange about all this. EJB offers five bean types.
Four of them have limited, if any, value. One of them is very useful and
also happens to be the one that is supported
today by COM+ and has been supported by since MTS 1996. Spooky, isn't
it?"

Keep in mind that there are many views here. From a EJB client
programmers point of view there are three types: EntityBeans, Stateless
SessionBeans and Stateful SessionBeans. From the EJB bean programmers
point of view there are some implementation choices to be made, but
there are really still only three basic types of EJB's.

And that's as far as the article has come. Part 5 (of 5) is not out yet,
but I will "happily" digest it too.

I remember saying (on this list, a year or so ago) that the "EJB vs MTS"
WhitePaper from David Chappell (available from www.microsoft.com) was
the worst piece of crap I had ever read. Well, mr Chappell has been
completely beaten by Sessions.

I hope you have understood by now that this article is way off,
completely inaccurate, and (IMHO) not even well-written. But people are
allowed to have "opinions" on everything, including me.

BUT, what makes this article a little different is that it is actually
part of a book that mr Sessions will release through O'Wiley. Yes, you
will be able to buy this crap in bookshops. And people will probably do
that. And this is where it gets dangerous: on the web people say stuff,
and others can easily respond to it and set things right, but when one
reads stuff in a book one usually assumes that the content is somewhat
accurate. This is certainly not the case here. If I were the publisher I
would be *very* careful about this book. I don't know about the COM
parts, they might be all fine and dandy, but this chapter is not
finished. In fact, it should either be completely rewritten or scrapped.
IMHO etc.

Comments? :-)

/Rickard

--
Rickard �berg

@home: +46 13 177937
Email: [EMAIL PROTECTED]
Homepage: http://www-und.ida.liu.se/~ricob684

===========================================================================
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".

Reply via email to