EJB specifies how developers should build components that can be accessed remotely and how EJB vendors should support those components. EJB components, called enterprise beans, automatically handle transactions, persistence, and authorization security, so that the developer can focus on the business logic.
Enterprise JavaBeans has been adopted by most distributed object vendors and is considered a standard for developing distributed object systems in Java. All EJB vendors must implement the same EJB specification which guarantees a consistent programming model across servers. In addition, because EJB is widely supported by many vendors, corporations do not have to worry about vendor lock-in; enterprise beans will run in any EJB compliant server.
Session beans can act as agents modeling workflow or provide access to special transient business services. As an agent, a stateful session bean might represent a customer's session at an online shopping site. As a transitive service, a stateless session bean might provide access to validate and process credit card orders.
Session beans do not normally represent persistent business concepts like Employee or Order. This is the domain of a different component type called an entity bean.
When a CMP bean is deployed, the deployer uses the EJB tools provided by the vendor to map the persistent fields in the bean to the database. The persistence fields will be a subset of the instance fields, called container-managed fields, as identified by the bean developer in the deployment descriptor.
In the case of a relational database, for example, each persistent field will be associated with a column in a table. A bean may map all its fields to one table or, in the case of more sophisticated EJB servers, to several tables. CMP are not limited to relational database. CMP beans can be mapped to object databases, files, and other data stores including legacy systems.
Typically, the server provides the JNDI look-up name either directly or via a system or server property. For example, with the WebLogic server, you would use a code segment similar to the following:
... Context c = new InitialContext(); UserTransaction ut = (UserTransaction) c.lookup("javax.jts.UserTransaction"); ut.begin(); // perform multiple operations... ut.commit() ...With J2EE implementations, you obtain the UserTransaction object with a code segment similar to the following:
... Context c = new InitialContext(); UserTransaction ut = (UserTransaction) c.lookup("java:comp/UserTransaction"); ut.begin(); // perform multiple operations... ut.commit() ...JNDI remote look-up names and property names vary, of course, across servers/environment.
In the previous scenario, however, the client application developer should address the question of whether or not it would be better to encapsulate these operations in yet another session bean, and allow the session bean to handle the transactions via the EJB container. In general, lightweight clients are easier to maintain than heavyweight clients. Also, EJB environments are ideally suited for transaction management.
<%@ page import="javax.naming.*, javax.rmi.PortableRemoteObject,foo.AccountHome,foo.Account" %> <%! //declare a "global" reference to an instance of the home interface of the session bean AccountHome accHome=null; public void jspInit() { //obtain an instance of the home interface InitialContext cntxt = new InitialContext( ); Object ref= cntxt.lookup("java:comp/env/ejb/AccountEJB"); accHome = (AccountHome)PortableRemoteObject.narrow(ref,AccountHome.class); } %> <% //instantiate the session bean Account acct = accHome.create(); //invoke the remote methods acct.doWhatever(...); // etc etc... %>Alternatively you can use a Java Bean to call EJB instead of writing the code in JSP.
The enterprise bean must not attempt to load a native library. This function is reserved for the EJB Container. Allowing the enterprise bean to load native code would create a security hole.
AccountHome acctHome = ... get a reference to the bean's EJB home.
EJBMetaData ejbMetaData = acctHome.getEJBMetaData( );
The EJBMetaData object implements the javax.ejb.EJBMetaData interface which defines methods for obtaining the class of the bean's remote interface, home interface, bean type (entity, stateful or stateless session), and the primary keys type (entity only). A reference to the bean's EJB home can also be obtained. Below is the interface definition of EJBMetaData.
package javax.ejb; public interface EJBMetaData { // Obtain the home interface of the enterprise Bean. public EJBHome getEJBHome(); //Obtain the home interface of the enterprise Bean. java.lang.Class getHomeInterfaceClass(); //Obtain the Class object for the enterprise Bean's home interface. java.lang.Class getPrimaryKeyClass(); //Obtain the Class object for the enterprise Bean's primary key class. java.lang.Class getRemoteInterfaceClass(); //Obtain the Class object for the enterprise Bean's remote interface. boolean isSession(); //Test if the enterprise Bean's type is "session". boolean isStatelessSession(); }Once a client application has a reference to bean's remote and home interface classes, normal Java reflection can be used to introspect the methods avaiable to client. Below is an example:
Class remoteClass = ejbMetaData.getRemoteInterfaceClass(); java.lang.reflect.Method [] methods = remoteClass.getDeclaredMethods(); for(int i = 0; i methods.length; i++){ System.out.println(methods[i].getName()); }There are no mechanisms a client can use to introspect on a the bean class itself. This makes sense since a bean, as a component, is represented by its remote and home interfaces. The bean class itself should not be visible to the client.
The EJBMetaData is designed to be used by IDEs and other builder tools that may need generic methods for obtaining information about a bean at runtime.
The remote interface, which extends javax.ejb.EJBObject can be a subtype or a super-type of remote interfaces of other beans. This is also true of the home interface, which extends javax.ejb.EJBHome. The bean class, which implements either javax.ejb.EntityBean or javax.ejb.SessionBean can also be a subtype or super-type of the bean class used by another enterprise bean. Deployment descriptors are XML files, so there is no Object-Oriented (OO) inheritance in the deployment descriptor.
Because an enterprise bean is not one object -- its the composition of several parts -- traditional OO inheritance is not possible. The constituent Java parts (remote, home, bean class) of an enterprise bean may themselves subtype or serve as super-type, but the bean as a whole (the sum of its parts) doesn't support inheritance.
The client needs the remote interface, the home interface, the primary key (if it is an entity bean). In addition to these, the client would need the JNDI factory implementation, and the remote and home stubs. In some EJB servers the Factory and/or stubs can be dynamically loaded at run time. In other EJB servers they must be in the classpath of the client application.
So, to answer your question, two users will never access an Entity Bean concurrently.
The biggest addition in EJB 2.1 is the new support for the Web-Services technology. With this new specifications, in fact, developers can expose their Stateless Session and Message-Driven EJBs as Web Services based on SOAP. This will mean that any client that complies with SOAP 1.1 will be able to access to the exposed EJBs. The APIs that will allow this and that have been added, are JAXM and JAX-RPC.
Another addition is the Timer Service, that can be seen as a scheduling built right inside the EJB Container. With EJB 2.1, any Stateless Session or Entity Bean can register itself with the Timer Service, requesting a notification or when a given timeframe has elapsed, or at a specific point in time. From a developer point of view, the Timer Service uses a very simple programming model based on the implementation of the TimedObject interface.
From the enhancement side, the Query Language is definitely the topic where the improvements are definitely more visible. The ORDER BY clause has finally been added. This will improve performance on orederd queries, because this will be handled by the underneath database, and not through the code by sorting the resulting collection.
The WHERE clause has been improved with the addition of MOD, while the SELECT clause has been improved by adding aggregate functions, like COUNT, SUM, AVG, MIN and MAX.
EJB, on the other hand, is a technology built atop of RMI but does so much more than allow java objects to be distributed. It is a framework that allows you to build enterprise applications by (among other things) abstracting transactions, database access and concurent processing.
The home interface is EJB's way of creating an object. Home interfaces act as factories to create session beans and entity beans. These factories are provided by the application container and take care of many low level details. Since RMI is a lower level technology, it does not offer the home interface. You would have to create it yourself.
When a client invokes a method on the stub, the container will look into the bean pool and see if there are any available bean instances that can satisfy that request. It will create more instances if all instances are currently being used by other clients.
You can control the size of the pool thru the deployment descriptor.
Think of a bank situation, where you have someone that would like to transfer money from one account to another. In this type of scenario, the client has to check that the user is authorized, get the status of the two accounts, check that there are enough money on the first one, and then call the transfer. The entire transfer has to be done in a single transaction.
As you can see, multiple server-side objects need to be accessed and possibly modified. Multiple fine-grained invocations of Entity (or even Session) Beans add the overhead of network calls, even multiple transaction. In other words, the risk is to have a solution that has a high network overhead, high coupling, poor reusability and mantainability.
The best solution is then to wrap all the calls inside a Session Bean, so the clients will have a single point to access (that is the session bean) that will take care of handling all the rest.
// One of the methods from the SessionBean interface public void setSessionContext(SessionContext context) throws EJBException { sessionContext = context; } // Then, when starting a new transaction UserTransaction userTransaction = sessionContext.getUserTransaction(); userTransaction.setTransactionTimeout(60); userTransaction.begin(); // do stuff userTransaction.commit();If you are using container-managed transactions, this value is set in a app server specific way. Check your app server's deployment descriptor DTD.
ejbPostCreate() is called after the bean has been written to the database and the bean data has been assigned to an EJB object, so when the bean is available. In an CMP Entity EJB, this method is normally used to manage the beans' container-managed relationship fields.
If you are using classes, use fully qualified class name such as java.lang.String and not just String.
<method-params> <method-param>java.lang.String</method-param> <method-param>int</method-param> ... </method-params>
ctx.getCallerIdentity().getName()
Where ctx is the instance of "SessionContext" passed to the Session Bean, or the instance of "EntityContext" passed to the Entity Bean.
Thus, if you're calling a Stateful Session Bean from a servlet, your servlet need to keep the reference to the remote object in the HttpSession object between client calls for you to be able to direct calls to the same object on the container. Likewise, if you're calling from an application, you only obtain the reference to the bean once and reuse the object throughout the application session.
For entity beans ejbRemove() is only called if the user explicitly deletes the bean. I think that is the reason why the engineers at SUN invented the unsetEntityContext() for this kind of bean.
The reason why we have 2 methods is that hashcode may not always return unique values. So the container also calls the equals method to verify the uniqueness.
<