blogger templates blogger widgets
This is part of a list of blog posts.
To browse the contents go to

Practical EJB

Below notes are from the Head First Book.

In EJB, remember, the Remote object (EJBObject) is the bean’s bodyguard. The bean sits back, protected from all client invocations, while the EJBObject implements the Remote interface and takes the remote calls



Session beans

Clients share the Home, but never the bean.Each client gets his own EJBObject reference and his own bean. The client never shares a bean with another client, although the meaning of “shares” depends on whether the bean is stateful or stateless.



Entity beans

Clients share the Home, and may share the bean.



Rules for local interfaces:

- Import javax.ejb.* (or use fully-qualified names).

- Extend EJBLocalObject (for the component interface) or EJBLocalHome (for the home interface).

- Declare one or more business methods in the component interface.

- All create methods in the local home must return the local component interface, and declare a CreateException.

- Any method you declare in the home or component interface can declare your own application exceptions, which must be compiler-checked exceptions (i.e. not subclasses of RuntimeException).

- You must NOT declare a RemoteException for any methods


isIdentical Method:



Session Beans:



Stateful session beans: Creation and Invocation


When ejbPassivate() completes, every non-transient instance variable MUST be a reference to one of the following:
- a Serializable object
- a null value
- a bean’s remote component or home interface, even if the stub class is not Serializable (in other words, you don’t have to worry about it!)
- a bean’s local component or home interface, even if it’s not Serializable (again, you don’t have to worry)
- a SessionContext object, even if it’s not Serializable
- the bean’s special JNDI context, or any of its subcontexts
- the UserTransaction interface (something you can get from your SessionContext—we’ll see that in the transactions chapter)
- a resource manager connection factory (like, an instance of javax.sql.DataSource)

ejbPassivate() - Your role - Make sure your instance variables are ready for passivation.
ejbActivate() - Your role - Reacquire your non-Serializable resources, or do whatever it takes to restore your state for use.

there’s a little teeny comment in the spec which says that there’s an exception to the rule that passivation behave just like serialization. The exception is that while serialization is required to bring back transient fields with default values, passivation doesn’t guarantee that!

What does this mean? Think about it. It means you can’t rely on transient to give you back your defaults, so after activation, you could end up with, well, anything in a variable that’s marked transient.

So, you are free to use transient, and it can make passivation more efficient, but the implication is—reset your transient variables yourself, in ejbActivate().

Things you can add if the bean is stateFULYou can have more than one create method.The create method can have arguments.The bean can be passivated, so you can write code in ejbPassivate() and ejbActivate().


Entity Beans

Client wants access to an existing entity:


Client wants to create a new entity:



Note:
In entity beans: create == new row, new EJB object
In stateful beans: create == new bean, new EJB object
In stateless beans: create == new EJB object (Container does not make a new session bean when the client calls create(), and does not pull one out of the pool until the client invokes a business method)

In entity beans: remove == deletes row, marks bean for GC
In stateful beans: remove == marks the bean for GC
In stateless beans: remove == Container doesn't care. The bean is already moved to the pool.

Synchronization of data


Forget about BMP, never used by anyone after EJB 2.0 spec.

Passivation difference between all 3 types:

- Stateless session beans go back to the pool without passivation (in other words, without getting an ejbPassivate() call).

- Stateful session beans are passivated when the Container puts them to sleep (possibly serialization) to conserve resources between client method invocations.

- Entity beans aren’t passivated in the way that stateful session beans are, but entity beans DO get an ejbPassivate() call when they’re about to go back to the pool (and an ejbActivate() when they come out of the pool).

- The most important point is that, unlike session beans, passivated entity beans are still live objects on the heap!

- There’s no such thing as a bean sleeping in a pool. Stateless beans, entity beans, and message-driven beans all use pools. And those pools are for living, RAM-using, on-the-heap objects.

- Only stateful beans are put to sleep (called, confusingly, passivation), but this has nothing to do with a pool.


Bean Construction

Before the client can use a bean for ANYTHING -- creation, finders, business methods, etc., the Container has to make a new bean instance for the pool. Bean CONSTRUCTION isn’t tied to entity bean CREATION.


Bean Creation



There are tons of rules about which methods you write and how it should be written.

CMP and CMR

The only difference between a CMP (container-managed persistent column data) field and a CMR (container-managed persistent relationship) field is the TYPE.

A CMR field is always another entity bean’s local interface type, or a Collection of them.

If it’s a Collection, it must be either java.util.Collection or java.util.Set.

You need a pair of abstract getters and setters for each CMP field (column values) and each CMR field (relationship with another entity).

APS

To define persistent fields and relationships, you need to create an abstract persistence schema. Defining the virtual fields isn’t enough. Your abstract persistence schema is a combination of your virtual fields in your bean class, plus some things you write in the deployment descriptor.

There are some naming conventions here too.

--
http://www.theserverside.com/discussions/thread/552.html

It seems to me that the J2EE platform has two competing solutions for storing client state: Stateful session beans and HttpSession parameters.

One of the most difficult thinks in the OO world is to give the right role to the right object.
Using Stateful session Beans is relevant when you need a "state machine" for your business logic, and it's is independent from how you "interact" with the system (WAP/WML, HTML, XML/B2B, etc).

HTTP session is for objects that drive the "application". It provides "state machine" for presentation logic.

There's an interesting issue with respect to timeout. If navigational state etc. is stored in the HttpSession and some other state is in stateful session beans, here's a possible problem scenario:

A user logs on to the system and does something that involves creating and using a stateful session bean. Then the user moves around for a while using functionality that does not touch the bean, thus repeatedly resetting the timeout of the HttpSession. It is then possible that the next time the user triggers a function that involves the bean, it may have timed out. The user of course expects his session to be far from timed out, since he's been working all the time. So he will not be very happy if the system tells him that, "sorry, you will have to log in again".

The only solution I can see to this problem would be to set the bean timeout so high/indefinite that the situation is unlikely to happen.

---

Transactions

You could do BMT and CMT.

BMT - short example.

Get a UserTransaction reference from your EJBContext.

context.getUserTransaction()
Start the transaction.

ut.begin()
End the transaction (commit or rollback).

ut.commit()
ut.rollback()

CMT - is how it needs to be done 99% of cases.

But how do we control the scope of transactions? Well, configurations as always. You don’t write anything transactional in your code except maybe an occasional call to EJBContext.setRollbackOnly() or EJBContext.getRollbackOnly()

CMT beans call getRollbackOnly() to find out if the transaction they’re in is already doomed. If the transaction is never going to commit, why should the bean waste time with lots of code?

An entity bean has ejbLoad() and ejbStore() to tell it when to synchronize with the database. If the transaction is about to commit, ejbStore() is called to give the bean one last chance to get it’s persistent state in order, ready to be written to the database. And if the transaction does not commit, the bean just gets another ejbLoad() to return it to its original pre-transaction state, and everything is fine.

But a session bean doesn’t have that luxury. No ejbLoad()or ejbStore() to tell it when it’s time to synchronize itself with a database. But if your session bean implements SessionSynchronization, you can give a session bean three new container callbacks, that notify the bean of three more special moments in the bean’s transactional life: when a transaction starts, when it’s about to end, and when it’s over.



No comments:

Post a Comment