I have the following questions on Bean Things that can be done in various methods.
1. In a stateful session bean's ejbCreate() method, you cannot mark a transaction for rollback, check if a transaction is marked for rollback. Hence I suppose you are not in a meaningful transaction context. If that is the case, how can you access another bean's methods and have resource manager access? If you say that you are in a meaningful transaction context in the ejbCreate() method and hence do these 2, why cannot you do setRollbackOnly() and getRollbackonly()?
2. In stateful bean's ejbPassivate() method, the bean is not in a transaction. In fact I read that if the bean is in a transaction, it will never be passivated. If there is no transaction, how can the bean access another bean's methods and have resource manager access in the ejbPassivate() method? I read that the container will allow a bean to access another bean's methods and access a resource manager(database) only if there is a transaction, but that is violated here. I would like to ask the same question for ejbActivate() and ejbRemove() of a stateful bean
3. How can a stateless session bean get a reference to its EJBObject in the ejbCreate() method when there might be no EJBObject at all? The bean could get created when there is no client and I suppose the EJBObject is created only when the client calls create(). I believe I read something about this in this forum, but didn't quite understand
4. When an entity bean is doing an ejbActivate() method, it has not yet been loaded. So, I suppose, the bean's context does not yet know the primary key of the entity that the bean is going to play. I suppose the context would get updated with the primary key of the entity only when the bean gets loaded which happens clearly AFTER ejbActivate(). This being the case, how can you ask the context for a primary key in the ejbActivate() method? Won't it return null as the bean is yet to be loaded? For that matter, how can you get a reference to the entity's EJBObject from ejbActivate()? I thought the bean would get linked to the EJBObject only after getting loaded with the entity's data. The same question for ejbPassivate().
I am following HFEJB and still in the 6th chapter and yet to read transactions chapter. But I still don't think the transactions chapter will have answers to all these questions. These Bean Things are becoming increasingly difficult to remember with each chapter because the book does not state the exact reason for each thing why you can/cannot do it in a particular method.If I think of the reasons myself, I feel it is quite illogical as I have stated in the above points. Any clarification would be greatly appreciated.
Question#1) Per Table 2 (page 80 of Spec), access to resource managers and other enterprise beans is allowed for ejbCreate(), ejbRemove(), ejbActivate() and ejbPassivate().
Hence I suppose you are not in a meaningful transaction context. If that is the case, how can you access another bean's methods and have resource manager access?
As you had mentioned, there is no meaningful transaction context. However, all these 4 methods are executed by the container in an 'unspecified transaction context' (for CMT). The chapter on Transactions talks about this behavior.
[I] Quoted from sec 17.6.5 of EJB Spec The EJB specification does not prescribe how the Container should manage the execution of a method with an unspecified transaction context�the transaction semantics are left to the Container implementation. Some techniques for how the Container may choose to implement the execution of a method with an unspecified transaction context are as follows (the list is not inclusive of all possible strategies): � The Container may execute the method and access the underlying resource managers without a transaction context. � The Container may treat each call of an instance to a resource manager as a single transaction (e.g. the Container may set the auto-commit option on a JDBC connection). � The Container may merge multiple calls of an instance to a resource manager into a single transaction. � The Container may merge multiple calls of an instance to multiple resource managers into a single transaction. � If an instance invokes methods on other enterprise beans, and the invoked methods are also designated to run with an unspecified transaction context, the Container may merge the resource manager calls from the multiple instances into a single transaction. � Any combination of the above.
Question #4) Ref 10.5.3 of Spec public void ejbActivate(); The container invokes this method on an entity bean instance at activation time (i.e., when the instance is taken from the pool and assigned to an entity object identity). The container must ensure that the primary key of the associated entity object is available to the instance if the instance invokes the getPrimaryKey(), getEJBLocalObject(), or getEJBObject() method on its EntityContext interface.
When the container decides to call ejbActivate(), the bean is still 'referenced' - which means the primary key is available. It is however true that the bean instance is not ready to serve a business call as it is not yet loaded with persistent data. We need to wait until ejbLoad for the sync-up.
Thanks for the detailed explanations. I was confused because the book said that the container will consider it risky and hence not allow resource manager access / another bean access when there is no transaction context in chapter 6. Looks like that is wrong, the spec seems to be clearer in this point.
While we are on this subject, could someone answer this question please.
Page 597, question 6, on HF EJB book, the answer says that ejbActivate() cannot call getCallerPrinciple(). As stated above, when the container decides to call ejbActivate(), the bean is still 'referenced' (and I think client is calling a business method). So why answer B is wrong?
Originally posted by Kevin Kumar: Page 597, question 6, on HF EJB book, the answer says that ejbActivate() cannot call getCallerPrinciple().
..because the EJB 2.0 specification says so; see page 180 (which is clearly identified in HFEJB page 597 for question 6) Table 4: Operations allowed in the methods of an entity bean in 10.5.5 Operations allowed in the methods of the entity bean class and page 257 (which is identified in HFEJB page 597 for question 7), Table 10: Operations allowed in the methods of an entity bean in 12.1.5 Operations allowed in the methods of the entity bean class.
There is actually no guarantuee that the bean is in fact referenced at this point - what is guarantueed is that getPrimaryKey() will work - don't draw any premature conclusions from that.
Advanced RDBMS servers have always allowed the DBA to collect statistics on the accessing patterns against the DB so that the server cache can be configured to improve performance for entities that are in high demand.
An application server vendor may want to implement something similar or even install customizable heuristics to identify high-demand entities. A high demand entity would always stay in memory - however there will be a time where it will have to be passivated for whatever reason. The server will want to get that bean back into memory once server resources are available again. Rather than slowing down the first client request for that entity, the server can get the entity bean up to the completion of the ejbActivate() where it has the access to the high-in-demand primary key but can't get any info about the client. Then the server can immediately run ejbLoad() when the first client requests that entity. [ October 24, 2005: Message edited by: Peer Reynders ]