Hi there Kathy, Firstly, way to go on a book so well written... HeadFirst EJB is one hellua read... gives Sidney Sheldon a run for his money ! Now coming back to EJBs, the bok says that one can obtain a reference to the EJB Object in the ejbCreate() method of a Stateless Session Bean. But it also says that a new EJB Object is created in response to every create() called by the client, and a bean is attached to the EJB Object only when a business method is invoked. So how does one get a reference to the EJB Object in the ejbCreate() method of the Stateless Session bean (which incidentally is called by the container only when it first creates the bean) Look forward to an answer...
Ritesh, Stateless session beans are created by the container and put in a pool, ready to go when a client calls some method on them. Since the bean at that point is fully formed, you can get its EJBObject. Remember that when clients call create() on a stateless session bean, the bean isn't actually created at that point--the stub is just set so the actual bean can be used. In fact, the stub won't be associated with an individual bean until a method is invoked. For an entity bean it's as you say. You won't be able to get its EJBObject until you're in ejbPostCreate(). Just remember that different bean types have different lifecycles.
I think there's an inconsistency between the ejbCreate (Table 3, spec 90) and the OID (Fig 12, spec 92). When ejbCreate is called on a stateless bean, the EJB(Local)Object has not been created (Fig 15 pg 94). The EJB(Local)Object is only created whey the client calls the create method (Fig 12 pg 94). So how can the ejbCreate call the getEJB(Local)Object (Table 3, spec 90)? Joyce
Remember that the callback methods are all defined by one interface, but used for all types of beans. In the case of entity beans, ejbCreate and ejbPostCreate are both called in response to an actual invocation by the client (create). For a stateless session bean, the container is in charge of instantiating the beans. That is, ejbCreate will be called by the container before the application is ready to go. For a stateful session bean, that is not the case. Clients still call create(), so ejbCreate will be called in response to that at some point. It is a bit confusing because the same interface methods are used for different bean types, but such is our misery.
Hi there This issue drives almost EVERYONE crazy at first. There are two things you might want to keep in mind here: 1) The diagrams in the spec (and in HFEJB) are a way to *conceptually* think about what it happening, but they do not represent exactly what is happening inside. As long as the system behaves according to the spec, the vendor can do whatever it wants... the Container can have an implementation that looks very different from the diagrams (in terms of what is instantiated and when) but it must BEHAVE as though it matches the pictures. 2) So... if the Container is required to return *something* to the SLSB in ejbCreate(), that represents the bean's EJBObject, then that is what happens. Even though it *appears* that the EJBObject is not actually created until *after* there is a client. So it DOES look like a contradiction -- the bean might be created BEFORE there's a client, yet the EJBObject is not created until AFTER there is a client request... but then how does the bean get a reference to an EJBObject during ejbCreate()??? Yes, it looks like a contradiction. And the answer is... The Container is required to give SOMETHING to the bean, during ejbCreate(), as a result of calling getEJBObject(), that implements the bean's component interface. For all we are to know, the Container gives ALL SLSB's a reference to the very same object. As others have mentioned, since all SLSBs are the same, it really doesn't matter. As long as the SLSB is connected to something that knows how to return the method return value to the correct client (i.e. the client that invoked the business method) then we don't really care how that happens. Again, the answer is: the Container is required by the spec to do this, even though it appears contradictory according to the lifecycle. That's the Container's problem... something the vendor has to deal with it, while WE get to enjoy the fact that while inside ejbCreate(), WE can get a reference to our EJBObject. And why is it important that we be able to get a reference to our EJBObject? Well, one reason could be because the bean, as part of its own internal initialization during ejbCreate(), might need to pass a reference to itself to some *other* object, and this is the bean's only chance to do that. In fact, this is why Entity beans have an ejbPostCreate()... so that they, too, have a chance to get a reference to their own EJBObject as part of the Entity bean's initialization process (and since Entity bean's can't get a reference to their EJBObject during ejbCreate(), the lifecycle includes a follow-up "part two" call -- ejbPostCreate() to give the Entity bean a chance to finish its initialization, especially if that initialization requires that the Entity bean get a reference to its EJBObject). Yes, there IS another reason why ejbPostCreate() matters now, because of CMR fields, but that is new to EJB 2.0 -- the original motivation for the ejbPostCreate() method was so that Entity beans could get a reference to their own EJBObjects during creation. cheers, Kathy
As Kathy mentioned earlier, it's not how the container actually does things that matters--it's how they look to the client. (That is after all what the specification is all about.) So, who knows what the container actually does. But, in ejbCreate (called by the container much earlier), an EJBObject is there and ready to go for anybody that cares. When create() is called by a client much later, she will get something that behaves exactly like the EJBObject that the actual bean could have retrieved in its own ejbCreate() along time ago. As further illustration, note that when the client calls create(), it does not result in ejbCreate() being invoked on the bean!