Howdy - I think this is a little too much for me to put in one post... but I'll try for some of it. The Container moves the bean to a pooled state whenever, well, whenever the Container wants to! The Container has three options for what to do after a transaction commits:
1) Call ejbPassivate() then send the bean back to the pool, where it stops having an identity
2) Leave the bean in the ready state, *associated* with a particular entity (in other words, linked to an
EJB object with a specific primary key, like, Fred Jones #42), but without keeping the bean synchronized with underlying *real* entity in the database. This means that when a client calls a business method on the bean, it will get a new ejbLoad() call, but it skips the ejbActivate() since its already active.
3) Leave the bean in the ready state, as above, but keep it synchronized with the underlying entity. That way, when the client calls a method, the Container is ready to go -- no ejbActivate(), no ejbLoad().
#2 is perhaps the most common and efficient, although some Containers allow you to specifically tune things to use option #3, but of course this means that you are locking any other application out of the database, and so this would work only if you can guarantee that the only way to get to the database is through the bean, so it's OK to keep the database row (or whatever locking is used) locked continuously for that entity.
However, even with #2, the Container should usually have enough 'smarts' to decide when its appropriate and efficient to send a bean back to the pool (perhaps because nobody has called a business method on this entity for quite a long time...)
What we know FOR SURE is that ejbPassivate() is called when the bean moves to the pool from the ready state, UNLESS it is after an ejbRemove(). So, there are really TWO ways to get 'back' to the pool from the ready state:
1) ejbPassivate() (at the end of a tx, or whenever the Container wants to after a tx commits)
OR
2) ejbRemove() -- when a bean is removed, the Container will *not* call ejbPassivate(); the bean goes straight to the pool after ejbRemove().
A bean can never call its own finders, but the Container will call a finder method while the bean is STILL IN THE POOL. Remember, to run a finder, the bean does NOT need to leave the pool and *become* some specific entity.
ejbSelect methods are another story. These can be called by a bean WHILE STILL IN THE POOL, if they're used with a home business method. OR, they can also be called while the bean is executing a business method as a specific entity (in other words, a business method from the component interface, thus the bean is definitely OUT of the pool and acting as a particular entity (Fred Jones #42 as opposed to Carol Foo #56)
Hope that helps...
There's a ton of pictures of all this in the book
cheers,
kathy