CODE EXAMPLES: Assuming that the code is legal (and you aren't tested on any Java syntax! -- If the code is illegal, that's because it won't work according to EJB rules or APIs) * If you see a call to getRollbackOnly(), what does that tell you? -- this MUST be a CMT bean! BMT beans can't call this, because they can use only the UserTransaction interface, which has getStatus(), but not setRollbackOnly() * If you see a call to setRollbackOnly(), what does this tell you? -- NOTHING, until you look at which interface the method was invoked on -- is it EJBContext? Then you have a CMT bean. UserTransaction? BMT bean. * If you see code that does not perform a narrow on the home stub, what does this tell you? -- this is a local client! * If you see code that *successfully* invokes getPrimaryKey(), what does that tell you? -- this is an entity bean * If you see code that successfully invokes getHandle(), what does this tell you? -- that you are looking at a remote interface; local interfaces aren't involved with handles -- if you see code that invokes a remove(pk) on the home, you know you are dealing with an entity bean (and that you are seeing code invoked on the home) -- if you see code that invokes a remove(handle), you know you are looking at a remote client -- could be session or entity -- and that you are seeing code invoked on the home -- if you see the no-arg remove(), then it must be the component interface SECURITY: * if you see isCallerInRole(aString), what do you know? - you are NOT looking at a message-driven bean - the method is invoked on an EJBContext - "aString" must be declared in the deployment descriptor as a security role REFERENCE -- be SURE you understand the difference between security ROLE and security role REFERENCE the reference is something the bean provider must put in, to tell everyone that he has hard-coded a role String. Remember, the bean provider does not *really* know what the actual security roles are in the company, so he just makes one up that sounds good, and then describes it in the deployment descriptor. The someone *else* must map from security role REFERENCES to security ROLES in the deployment descriptor (often this is the Application Asssembler), and finally, the Deployer must map from security ROLES (in the deployment descriptor) to *real* security roles for principals/users/groups in the real "operational environment". This final mapping is NOT part of the EJB spec! It is NOT done in the ejb-jar.xml document. Session Beans: -- know the lifecycle -- -- stateless session beans ejbCreate is not in any way connected to a client calling create -- same with remove -- passivation is ONLY for stateFUL beans. -- they will never be passivated while in a transaction! -- If a stateful bean times out while passivated, the container will NOT "wake the bean up" (i.e. activate) just to kill it. So, the bean will be killed WITHOUT getting a remove() call. So don't rely on remove() [which will also be missed if there's a server crash] -- be sure you know that setSessionContext is called very early in the bean's life, and only ONCE (this is true for all beans), and that within setSessionContext, you do not yet have access to your component interface, you must wait until you are in ejbCreate! -- do not do ANYTHING in your bean's constructors. An object does not have any "beanness" at that point. It is *legal* to put some code there, but don't. -- a transaction on a stateFUL bean can span multiple invocations from the client. In other words, you can start a tx in one method and then leave it uncomplete when the method ends. -- a stateLESS bean must complete its tx before the end of the method -- a stateLESS bean must NOT implement SessionSynchronization TRANSACTIONS:
-- BMT is for Session (both types) and Message-driven beans ONLY --- A BMT bean will not run in a tx unless it is the tx started by the bean itself. -- A BMT bean's transaction will propogate to other beans that the BMT bean calls.
-- a BMT bean must not start one tx before completing the previous one. -- BMT means must never call setRollbackOnly or getRollbackOnly on the context. CMP: -- know the SIX transaction attributes, and know exactly how they will behave, depending on whether or not the calling method is in a transaction. -- know that MANDATORY and NEVER will throw exceptions -- which transaction attributes can an mdb have? Only Required and NotSupported! The others do not make any sense for an MDB, since it can NEVER be invoked with an existing tx (it is only the container who invokes the onMessage()) -- know that a bean with SessionSynchronization must NOT use Never, NotSupported, or Supports. In other words, a bean that wants to know about its tx status better be in a transaction! -- look up in the spec what it means to have "an unspecified transaction context", and understand the circumstances in which a method will run that way. -- know exactly WHICH methods must have a tx attribute; - Session: just the business methods from component interface, nothing else -- Message: just onMessage() -- Entity -- all the business methods, the methods YOU define in the home (create(), finders, etc.) AND the three remove() methods from the two interfaces! (or two remove() methods if its local) EXCEPTIONS: -- know the difference between System and Application exceptions. -- most importantly, know that only System exceptions result in an automatic rollback. For application exceptions. -- Know that application exceptions go to the client AS-IS (in other words, exactly as they were thrown by the bean / conainer) -- System exceptions are wrapped in a RemoteException for remote clients -- local clients WILL get an EJBException, but a remote client never will.
-- you must know which are checked and which are not, so that you know what your responsibility is for declaring them, and what the client's responsbilitiy is. EJBObject is a runtime exception, so you can throw it anytime without declaring Know the FIVE application exceptions from javax.ejb: Finder --ObjectNotFound Create -- DuplicateKeyException Remove Know that a client might not always GET the DuplicateKeyException even when that is the problem. Don't count on it. Know the difference between ObjectNotFound and NoSuchObject. ObjectNotFound is ONLY for finder methods, and only for single-row finder methods. To remember: "ObjectNotFOUND goes with FINDER methods" NoSuchObject means that at one point the client had a reference to an EJBObject, but that EJBObject is no longer there -- in other words, you have a stub but the thing it connected to (the remote object) is gone. Know that NoSuchObject is a standard RMI exception, but that now there is a NoSuchLocalObject exception as well. Know that even though RemoteException is a checked exception, is is NOT an application exception. Anything else you declare in one of your interfaces IS an application exception (which must also be a checked exception). Know that system exceptions cause the bean to be discarded, application exceptions do not. Know what it MEANS to discard a bean: -- stateless session clients can still use their EJBObject reference (container just grabs a different one from the pool) -- stateful session beans will have to go back through the home again and start over -- entity beans can still use their EJBObject reference (the pool...) When you believe a client cannot recover from something that YOU caught in your bean code, throw an EJBException to the container. If you are throwing an application exception, then you must decide yourself whether the tx should be rolled back. Know the SCOPE of java:comp/env -- -- it is per BEAN, not per JAR or application -- Know that it is the bean's private environment. Understand: * Environment Entries -- if the bean provider coded one in, the provider MUST announce that in the DD -- the app assembler or bean provider can put in the value (probably the app assembler) but the Deployer MUST ensure that there is a value * be sure you know how the DD element matches what you put in code to access it. (java:comp/env/foo should be just "foo" in the DD, without the quotes) * Be sure you know the TYPES that an environment entry can be! Be sure you understand that tx attributes in the DD can be specified on a method-per-method basis, and KNOW what the elements look like for specifying a tx attribute. Be sure you understand how the wildcard "*" works for this. Know the DD tags for the security role references and roles Know what it means to access a bean from a bean: that you use an ejb reference. Be familiar with the DDelement, and how it maches the code; java:comp/env/ejb/Advice means: "ejb/Advice" in the DD -- know all the rules for the circumstances for load and store, etc. if you see ejbLoad, you know you are looking at an entity bean, and you know that the bean has already been populated with the state from the persistent store (because we are ONLY talking about CMP) -- I'm not going to go into the CMP stuff here (too much), so just be familiar with the way that CMP and CMR works!