Some points that I jotted down on differences between EJB 2.0 and 3.0. Hope these are helpful.
Differences between EJB 2.0 and 3.0
-- In 2.0, you need to define the home interface for a session bean. In 3.0 you dont need to define the home interface.
-- In 2.0, the remote interface needs to extend the EJBObject and methods must throw RemoteException. In 3.0, your interface can be a simple POJO interface and there is no requirement to declare any remote exception. In fact, there is no need to define any business interface in 3.0 for your session bean (the business interface will get generated automatically by the container). But in that case, any public method defined in your session bean will be exposed to the calling clients. It is better to define a business interface, so that you can control which methods of the session bean are exposed.
-- There are no annotations in 2.0 and the behavior of the session bean is controlled by a deployment descriptor. In 3.0, you use annotations to define behavior eg: @Stateless defines that this is a stateless session bean. In fact, if you don't define annotations, then the container uses defaults eg: CMP is the default persistence mechanism which will be used if you dont specify any annotations for the same. So, it is best to define annotations only if you are doing something different than the default behavior. If you define annotations as well as define the same in a deployment descriptor, then the value defined in the deployment descriptor will have priority.
-- In 2.0, your session bean should implement the SessionBean interface, and consequently you need to define/implement the callback methods such as ejbActivate and ejbPassivate. In 3.0, your session bean is a POJO and does not have to implement any interface. Consequently you dont have to define the callback methods. You should define them only if you need them. Moreover you can use annotations such as @PrePassivate (followed by the method) which would indicate to the container that the following method is to be called before passivating the bean.
-- Another difference is in the way clients call the bean's methods. In 2.0, you need to use the initial context to look up the home jndi reference, and then use a PortableObject's narrow method to cast it to your home interface reference, and further use the home.create method to create the remote reference. You can then use the remote reference to call the beans method. In 3.0, this has been simplified. You just declare a remote reference using the @EJB notation and you can directly call the methods on the session bean using the remote reference.
-- Further in 3.0, the entity beans from 2.0 have been replaced by JPA and Entity classes. They use an ORM mechanism to persist data in the database and are more efficient than Entity Beans.
-- In 3.0 you have the interceptor facility available which is similar to the Servlet filters. The interceptors can be defined for Session beans and Message Driven beans, and can be used to intercept the request and do some kind of preprocessing such as logging.
-- In 3.0, using annotations you can expose 'Stateless Session Bean' as a Webservice by using the @Webservice annotation, and by using the @Webmethod to expose certain public methods as a webservice API. The tehcnology used here is JAX-WS and the parameters used in the exposed methods must be JAXB compliant.