John Daniels:
Further to the discussion about EJB transaction semantics that we had at the recent "retreat" meeting, I've been re-reading the spec:
-------------
[Spec V1.0 March 21 1998 pg 24] A [session] Bean must write any cached database updates prior to the Bean's transaction completion, and it must refresh its copy of any potentially stale database data at the beginning of the next transaction. ... A container may only passivate a session Bean when that Bean is *not* in a transaction.
-------------
In fact, it's pretty clear from the spec that I was completely wrong in my belief that Bean identities cease to be valid at the end of a transaction. Both session and entity Beans have long-lived identity. The lifetime of a session Bean is, roughly, decided either by the client (who can explicitly destroy it) or by the container (who can throw it away if it gets bored or if the server crashes!). The implication of this is that a client had better not rely on the persistence of any state held by a session Bean, which is, in any case, not transactional (i.e. doesn't roll back). The client must always be prepared to recreate the Bean.
Entity beans are much more robust. The server must ensure that references to such Beans survive crashes. Indeed the spec says:
-------------
[pg 57] Containers that store long-lived entities will typically provide handle implementations that allow clients to store a handle for a long time (possibly many years).
-------------
I'm not entirely clear what a handle is, but it seems to be a serialisable representation of a Bean reference. For some reason, this is all different from the way you serialise a reference to a session Bean.
One other point. Access to session Beans is strictly serialised by the container. So you'd better be careful about having one session Bean invoke another, in case it then invokes the first (a "loopback call") and deadlocks. This is explicitly discussed on pg 28. Session Beans are never shared across clients, so simultaneous access isn't a problem.
Entity Beans seem to work differently. Since they *can be* shared by multiple clients, the container has to ensure correct behaviour. It can do this [pg 68] either by creating one memory instance per client, and having the database ensure correct updating behaviour, or by having a single memory instance and serialising access to it. If it chooses this second strategy, it will have to manage some kind of object table. It's not clear to me what the tradeoff is here.
In addition, an entity Bean can be marked "re-entrant", in which case the container will allow "loopback calls" provided they are *in the same transaction context* (Syntropy lives! See Designing Object Systems, pp 231-234). However, the spec contains dire warnings about doing this, because the container may not be able to distinguish between a loopback call from another bean and a concurrent call (in the same transaction context) arriving from the client. Concurrent calls are illegal in EJB but, if you've marked the Bean as "re-entrant" the container might not notice. So you'd better be careful in the client that two or more threads don't try to make calls to a re-entrant Bean at the same time. I guess this could easily happen, given the event model of many GUIs.