We have started to use EJB about 2 months ago.
At first glance it all seemed perfect - you can
create EJB beans and relations with just some mouse
clicks in JBuilder, then deploy and enjoy it. And CMP
relations are very handy.
But then we started to test our application over modem
link. And it was awful - every 'get'/'set' method on
an entity bean results in a network query.
The only solution we have found is "value objects" and
"command" patterns. But you can't use so useful CMP
relations with them.
So we invited our own solution - construct value objects
"on the fly" using reflection (like JBoss does). This value
objects implement local interfaces of their beans. So we load all bean's simple (not EJB-relations) properties into "smart value object" when it is constructed on the server, after this the new "smart value object" is serialized and returned to client. Client works with this object like with usual CMP bean.
But this pattern allows us to do much more. "Smart value object" intercepts all calls to its methods, so it can implement lazy-load (in a daemon thread, for example) of the EJB-relations automaticaly creating value objects when relations is accessed. So client can get a mirror copy of beans graph and work with them like with normal beans (of course, business methods are not supported) - get and set their fields, get and set relations.
Besides, command pattern can also be implemented on such model - every get/set method on value object generates command, which is put in local command queue (possibly with information how to undo this command) and transmit all the queue to server in a single network query.
This pattern proved to be useful in two our projects.
PS: please, excuse me for my awful English :)