JDO vs. Entity Beans: A Modest Proposal
by Marek Mosiewicz02/27/2002
When Sun introduced the EJB 1.1 spec (including Entity Beans) two years ago, it was a revolution in enterprise computing. Experience revealed, however, that it was not perfect. The remote interface is slow and it makes creation of fine-grained objects difficult, in many cases.
The Java Data Objects (JDO) interface was later introduced as a new interface for storing objects to a data store, which in many cases could be a replacement for Entity Beans. At first glance, JDO seems to be a solution for Entity Beans' performance problems. In most applications, data operations are retrieving and setting field values. Most JSP pages simply display or change data from databases. In this case, the remote interface is huge overhead; remote getters and setters are unnecessery, especially if you would like to call the same getter many times. (With remote methods, you can’t afford to call a remote getter many times.) In this case, it is much more reasonable to retrieve data so that the client can manipulate it locally, and then send it back to the server.
JDO realizes this approach. In fact, it could be considered an object-oriented JDBC interface. For many developers, it seems to be the perfect solution, but it is not enough.
The real power of Entity Beans is in their server-side business logic, which is not available in JDO because of its client-side orientation. This is not easy to see, given the current status of Entity Beans, which have poor support for object-oriented design patterns. There are no real virtual methods or inheritance. But let’s try to imagine EJB with all real object features (in fact, this is not easy to do, and probably will take a long time to achieve). Then, server-side logic becomes a powerful tool for the application designer. For example, a customer entity with a getCreditLimit() method can be implemented differently for different types of cutomomers. With such Entity Beans, it becomes possible to create real object-oriented frameworks for business applications. But is there any way to make EJB more efficient in simple get-set operations?
EJB Interface Improvement
In EJB 2.0, there are plans to introduce dependent objects. This solution would provide some improvement in EJB performance; however, it is not perfect. In many cases, treating objects as dependent usually cannot be known at design time. One object must be an entity in transaction; so it would be enough to have a local copy when we only want to display it.
Therefore, here’s a solution, which allows for decisions in runtime. There are proposed interfaces; first is a data object interface, which stores only data:
interface EModel extends
PossiblySomeKindOfResultSetNavigationInteface ???{
setField1();
getField1();
}
This is the Entity Bean interface:
interface ERemote extends EJBObject{
setField1(); //equivalent to EModel methods
getField1();
EModel getModel();
void setModel(EModel)
void doSomeServerSideBusiness();
}
The home interface could also have the special findByModel(EModel model) method to get an entity object, if we have only a data object (if EModel would hold the EJB handle or ID). We could do even more. There is no need to define a single EModel. We can have serializable objects, which are held by a given model getter or setter. This could be achieved by introducing something like this into the remote interface:
Object getModelWith(Object modelGetter,
Object getterHintsOrMapper);
void setModelWith(Object modelToSet,
Object modelSetter, Object setterHintsOrMapper);
This would give us incredible flexibility. There could be pluggable mapping extensions to our EJB container for XML, JDO, or SQL ResultSet.
Some of these extensions would have to be written by developers on an individual EJB basis. Many could be more generic, written with mapping tools like Castor. There could be many XML mappings for one EJB. This would give us a chance to handle many XML messages. For example, an entity invoice could handle many invoice messages.
Developers, not application server providers, could introduce the interfaces shown here. If introduced by a server provider, mappings could be created automatically. These could also be faster, if containers offer some special API. For example, a RDBMS persistence provider could generate and execute SQL directly from an XML message.
Also, when using finders, it should be possible to decide what is needed: entity or data. Then finders could also have a mechanism to retrieve only selected fields for the client, if data has been chosen. Otherwise, it would be annoying to retrieve collections of large data objects if we only need their names.
As I remember, the early IBM San Francisco framework followed a similar approach. There was a special transaction demarcation mode, which indicated objects could not be persistently modified. This allowed us to receive, copy, and operate on them locally, as long as the client had implementation.
Marek Mosiewicz is a senior software developer in TALEX S.A.
Return to ONJava.com.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 4 of 4.
-
An approach
2002-03-06 04:33:25 spruzens [Reply | View]
Why not give entity bean writers the option of having their interfaces implement another interface, RemoteStreamable (perhaps someone could pick a better name). RemoteStreamable would have a single method:
public interface RemoteStreamable {
Entity beans inplementing RemoteStreamable have these characteristics:
1. When the first get or set is called on the interface, the current state of the entity is streamed to the client. The container may chose to lock the bean optimistically or pessimistically at this point.
2. All gets and sets operate on the client's local copy of the bean.
3. When the client calls the release() method, the bean's state is streamed back to the server for persistence.
4. Depending on how the server implements locking, a second client may have to block waiting for the first client to call release() (a problem if the first client never calls release()), or the second client may get an instance of the bean, with either client's release() calls throwing a ConcurrentModificationException if required.
Locking strategy would perhaps be set in a deployment descriptor.
RemoteStreamable entity beans in session bean facades would continue to inherit the transactionality of the method they are used in, with an implicit call to release() at the end of the session bean method (or indeed transaction boundary).
-
An approach
2002-03-06 04:33:23 spruzens [Reply | View]
Why not give entity bean writers the option of having their interfaces implement another interface, RemoteStreamable (perhaps someone could pick a better name). RemoteStreamable would have a single method:
public interface RemoteStreamable {
Entity beans inplementing RemoteStreamable have these characteristics:
1. When the first get or set is called on the interface, the current state of the entity is streamed to the client. The container may chose to lock the bean optimistically or pessimistically at this point.
2. All gets and sets operate on the client's local copy of the bean.
3. When the client calls the release() method, the bean's state is streamed back to the server for persistence.
4. Depending on how the server implements locking, a second client may have to block waiting for the first client to call release() (a problem if the first client never calls release()), or the second client may get an instance of the bean, with either client's release() calls throwing a ConcurrentModificationException if required.
Locking strategy would perhaps be set in a deployment descriptor.
RemoteStreamable entity beans in session bean facades would continue to inherit the transactionality of the method they are used in, with an implicit call to release() at the end of the session bean method (or indeed transaction boundary).
-
An approach - continued
2002-03-06 04:44:04 spruzens [Reply | View]
...bits got lost in last post...
1. The interface is:
public interface RemoteStreamable {
public void release() throws ConcurrentModificationException;
}
2. Non gets/sets (i.e. business logic that runs on the server) would cause an implicit stream back to the server of the current state of the client's bean - but *not* a release(); the client would still hold the lock.
simon.






If you are generally interested in persistent object database issues, and if you have access to a Mac OS X computer, also check out FScript. It may be the real replacement of SQL for OO development instead of a wrapper.