, Amide Ude wrote:
- Should we really use Replicated objects when data is not read-only? i.e in case of entity beans should we copy data from entity beans into data transfer objects and pass them by value? ... we use entity beans(CMP) to reduce complexity in coding and designing. By using the approach (which according to me is complex), are not we violating the purpose?
Amit hit a nail on the head when he stated "we use entity beans(CMP) to reduce complexity in coding and designing". However, the problem is that this reduced complexity comes at a substantial
runtime performance penalty. The problem is that every call to an Entity EJB:
- Has network overhead (potentially)
- Has thread-safety and synchronization overhead
- Has persistence overhead (if it's a CMP Entity bean)
- Has transaction overhead
This is what has led us to use (relatively bizarre) strategies like UseDataTransferObjects
to mitigate the runtime overhead.
My problem with the EJB spec is that you do not have enough choices. Every bean is always distributed, threadsafe and transactionable. All CMP beans have the previous qualities but are also persistent. What I want is a way to choose 1 or More, but less than ALL of the preceeding qualities.
Now, there has been some talk on the EJB-INTEREST mailing list about "Dependent Objects" which may be a way to achieve some of this. However, I'd like a way of making all four axes independent, so that you can choose what qualities you want in your beans.
I will second KyleBrown
's opinion. When we talk about thin clients accessing enterprise data using EJB's, should the client be using the EntityBean
s and SessionBean
s directly at its end? My opinion is that the client should be concerned only with the representation of the data, and not bother about the way it is being accessed. So the client should be viewing only simple Beans or ReplicatedObjects?
According to some rumblings from Sun, something to help mitigate this situation might emerge in a late draft or revision of EjbTwo
I agree. The main problem with client apps that directly communicate with remote Entity beans is the network overhead caused by remote method calls to get/set individual properties. A frequently suggested solution to this problem is to use Session beans to return DataTransferObjects?
containing requested data.
IMHO, a better solution is to have the Session beans serialize domain objects as XML and have the client create an object representation of the data from the XML. If done generically, you can have one session bean with the basic CRUD methods that knows how to deal with every object type.
Seriously - try MicrosoftDotNet. You've got what you want - today.
On the client, you have a single broker component responsible for object materialisation from the server and caching objects locally.
Using some standard OO persistence techniques (such as lazy instantiation of related objects) it is reasonably easy to provide the client with a true in-process OO view of the data.
The advantage of using XML is that it makes it easier to support different types of client.
Web apps are different because all method calls to EJB's tend to be in-process so using Entity beans is more practical <- maybe this is what they where intended for ??
The general trend is to use "bulk accessors" to pass objects by value through RMI-IIOP. This is easily translated into XML, though there is no standard data binding as of yet.
Even if inter-bean calls are in-process, the spec says you need to pass all parameters by-value in case they're not. It's usually a vendor-specific flag to toggle "pass by reference" for performance tweaking (some Object/relational mapping products require this for caching, too).
EJB 2 fixes things somewhat since EJBLocalObject and EJBLocalHome allow freedom on the "all EJB's are remote" constraint. I assume the authors are taking the angle that security & transaction overhead are good things. They're also promoting CMP Entity Beans to be fine-grained, a major change in direction from prior approaches.
So, the major remaining problems are:
- EjbDependentValueClasses require manual mapping to a) JDBC ResultSets? or B) CMP entity beans. This can be tedious especially when data validation isn't complex or even necessary. A PropertyContainer? idiom could help in this case.
- Locking / Synchronization. If you cache your entity beans, they still are subject to that dreaded full-bean exclusive lock from Commit Option A, unless you use a vendor-specific object locking API (such as those for TopLink or GemStone). If you don't cache your entity beans, your DB synchronizes access, a more generally useful approach since it's fine grained (i.e. row-level, object-level, or page-level).
EJB's aren't necessarily over-specified, because they do require some difficult constructs to deal with fundamental problems in transactional and distributed object computing. The goal of EJB is to transcend those problems with a specification so one can build a transactional business system without having to be an expert. It's a common learning and vendor ground. It's not perfect because it has to make hard choices about how to deal with certain problems, and a lot of those choices in EJB 1.0 where, well, naive. The intentions of the authors were never appropriately clarified until recently (with some of the EJB 2 changes, and VladaMatena
is a pattern I've been updating in ComponentDesignPatterns
to include more variations related to recent technology updates. For example, MessageDrivenBeans?
in the EJB 2.0 spec are a great way to keep replicates of a remote object up to date. But the key theme is that if you've got the luxury of being able to perform event notifications to your clients (holders of the replicates of the server's replicated object), then you can build a ComponentBus
into your FacadeAtTheDistributionBoundary
so that a DistributedCommand?
can be called to essentially subscribe to the topic associated with the object and receive its initial serialized snapshot. From that point forward, event notifications include small delta messages are propagated to replicates to maintain consistency.
We are facing the same problems mentioned above. We have object trees that are passed to clients. This can be easily done using serialization. The hard part is to get the changes back to the server. We are using Versant (an OODBMS) and need to update the object in the database with the changes made on the client.
Thus the problem lies in creating and transporting a 'diff' of two object trees,
where the 'diff' is created on the client and merged on the server.
Does anyone know a generic solution (i.e. a pattern :) for this problem ? (using RMI)
Yup. The CommandPattern is a solution. Whenever you allow a user to change an object tree (through a GUI) create a Command object that represents the change (it can be as simple as a "key" to find the object and the method selector and arguments of the changing method. This assumes you use reflection to replay the commands.). Place the Command change on a stack. When the user is done, send the Commands to the server and then ask them to replay themselves. It's certainly easier than a dual-tree traversal in trying to do a diff.