This week's book giveaway is in the Agile and Other Processes forum. We're giving away four copies of Software Teaming: A Mob Programming, Whole-Team Approach and have Woody Zuill and Kevin Meadows on-line! See this thread for details.
Howdy Unfortunately for all of us, the J2EE team used ejbActivate and ejbPassivate to mean two COMPLETELY different things -- one for stateful beans, and one for entity beans. The behavior of the methods is so different and unrelated, that you should look at them as separate methods, and don't let the fact that the names are the same confuse you. We'll look at them separately here: 1) Stateful session beans (remember, stateLESS beans do not get passivated, so the methods are never called on a stateless bean) Passivation is used to help give stateFUL session beans a weak attempt at having better scalability. Imagine you have 100 customers with references to 100 different shopping cart session beans. At any moment in time, perhaps only TWO of those customers are actually in a method invocation on the bean. Far more time is spent BETWEEN method calls than IN method calls, so there is a lot of wasted resources while a shopping cart session bean just sits there on the server. But... with passivation, the stateful bean can be put into a kind of 'sleeping' state, which *might* be serialization, but is often something faster and more efficient. The bean is put into some kind of temporary / secondary storage which it stays in until the client makes a method call on the bean, or the bean times out. When the Container realizes, "Hey, this client hasn't done anything for a while, so I think I'll passivate it..." the Container calls ejbPassivate() on the bean. This gives the bean (which means YOU as the programmer) a chance to get the bean READY to be passivated. Usually, the method is empty because there is nothing you need to do. But if you have any non-serializable variables, which are not marked transient, then you must explicitly set them to null in ejbPassivate(). (Actually, you should also set even transient variables to null, because the spec does not guarantee that transient variables will come back with default values.) There is a whole list in the spec of what state your bean's instance variables must be in by the end of ejbPassivate(). When the client comes back and decides to put something else in their cart and call addItemToCart(someCoolThing), the EJB Object gets the method call and then panics and starts yelling at the Container to go get the bean out of passivation! So the Container calls ejbActivate(). If ejbPassivate() was empty, this method probably will be too. Basically, ejbActivate() is a chance to undo whatever you did in ejbPassivate(), and restore any instance variables that you nulled out. ========================== 2). ENTITY beans Forget everything I just said about ejbActivate() and ejbPassivate() for session beans, because it has a completely different meaning. Imagine you have a Customer entity bean. At any given time, you might have one bean representing Fred Jones, #12, another for Jack O'Bryan, #42, and still another for Dave Cronin, #343. These beans are *being* the entities that ACTUALLY exist in the underlying database. Remember, entity beans are only representations of something else.. something REAL that lives in a database. (Technically, the spec says, "underlying persistent store", which isn't necessarily a database, but for all practical purposes, it WILL mean a database, and in fact usually a *relational* database). But chances are, if there are no clients currently interested in the other 50 entities in the underlying Customer table in the database, then there are no other entity beans being used to represent real entities. So, what happens to the other beans? The other Customer beans are sitting in a pool, waiting to *become* some entity from the Customer table, when a client comes along and requests to, say, "find Carol Smith #78". The entity beans in the pool (the Container decides how many to keep around in the pool, although it will almost always be a MUCH lower number than the number of rows in the table!) are just hanging out, floating on air mattresses and drinking exotic drinks with umbrellas sticking out of them. Until... a client requests an entity bean for an entity not currently "alive". The Container says, "Oh, looks like we need someone to be Carol Smith #78" and pulls a bean (perhaps randomly) out of the pool. When the bean comes out of the pool, ejbActivate() is called, followed immediately by ejbLoad() (which tells a CMP bean that it has now been loaded with data from the database). When the client is done with the transaction, the Container calls ejbStore() one last time, so that the current state of the bean is used to update the underlying row for that entity, and THEN the Container calls ejbPassivate(). What goes in ejbActivate() and ejbPassivate() for an entity bean? Probably NOTHING. This set of methods has very little value, because you can almost always find a better method in which to do the work. People used to think, "I'll get my database connections in ejbActivate(), then release them in ejbPassivate(), so that I only hold the connections while I'm active." But that isn't an efficient strategy, because not all Containers will immediately passivate a bean when the client is finished with the transaction. The spec says that Containers have THREE options for what to do with the bean after a transaction is committed, and only ONE of the three options involves ejbPassivate(). So using ejbActivate() and ejbPassivate() for grabbing and releasing resources might lead to holding resources much longer than you need to, which makes those resources unavailable to some other bean that might really need them! Hope that helps... cheers, Kathy "Finally an EJB book that teaches you everything you need to know and keeps you laughing while doing it." - Kenneth Saks, Sun Microsystems, Lead Developer of the J2EE RI Container