“Controlling your application” (the business logic) EJB Session Beans “Controlling your application” (the business logic)
Model 2 with J2EE EJB’s Model Two Architecture Control Model Web Container EJB Container View Control Model Web Server HTTP Request Servlet (request handler) Entity EJB Entity EJB Session EJB Session EJB Session Bean Java Bean Java Bean Java Bean <<creates>> <<forward>> HTTP Response The Model 2 architecture breaks up the Model-View-Controller pattern such that each part of the model can run in a different container on a different server. What is the purpose of breaking the pattern in this way? Adaptability Flexibility Scalability Thus far we have implemented the View and the Control. To implement the Model we will need to develop a seaparate tier of code to handle all of the dataaccess. One way to do this is to create your own custom code (A Data Access Object) Create your own custom code to access the database Access the database or flat file Manage persistence of data System dependent Database/file dependent JSP (view builder)
Advantages Automatic Transaction management Resource management Security Modularity Simple programming interface Advantages Remember that one of the advantages of Session Beans is that the Application Server stores the EJB in memory in the “bean pool”. This allows the bean to remain in memory and shared over large number of clients. Entity Java Beans work the same way but for data objects. Much simpler programming interface for client to access that data Greater portability, maintainability, reliability, code re-use Automatically handles transaction processing for you
Clients View of Session EJB Remote Interface Client Program Bean (Implementation) Local Interface Structure of Entity Java Beans Similar to Session Beans. There is a Client view and a Server View The client view – represents the client programmers interface view to the bean. These are the methods that you as a programmer have access to. This is the public interface to the bean. It acts as a façade to hide the complexity of the bean implementation from the developer. The bean class – represents the detailed implementation of the bean. All of the methods in the interface and the all other required methods by the container are implemented in this class Client Interface Implementation
Session EJB Developers View <<EJB Session Bean>> OrderControl <<Realization>> CustomerOrderEJB +startOrder() +addItem() +deleteItem() +checkout() +cancelOrder() +checkOrder() <<Remote Interface>> CustomerOrderRemote +startOrder() +addItem() +deleteItem() +checkout() +cancelOrder() +checkOrder() The actual implementation of the Home and Remote interface methods is done by creating the EJB Entity class. This class is some times called the “implementation” or “bean” class. The implementation class contains class variables that refer the Context object that EJB is running in and the different data elements represented in the Entity bean. It contains default constructor method and methods that implement the required methods of the home interface and the remote interface. There are also other methods that are used to manage the Entity bean such as ejbPostCreate(), ejbActivate(), ejbPassivate(), ejbLoad(), ejbStore(), setEntityContext(), and getEntityContext(). Client Interface Implementation
Remote vs. Local Entity Beans Please Use Whenever Possible!!! Remote Session EJB Anywhere on the network Pass by value Local EJB are faster but not as flexible, scalable and adaptable On same server as Session Beans No network traffic Pass by reference
Stateful vs. Stateless Transactions Please Use Whenever Possible!!! A stateless transactions is One call to server Does not the save transaction state data No memory is allocated in the pool for each session with a client EJB is never passivated or activated Stateful transaction Used for multi-step transactions Saves state data for each client session Memory is allocated in pool for each client session EJB is passivated and activated
Stateless Session Bean LifeCycle Does not exist timeout, @PreDestroy, Class.newInstance(), @PostConstruct Ready in pool Business method
Stateful EJB Session Bean Lifecycle System exception Does not exist Timeout, @PreDestroy Class.newInstance(), @PostConstruct() Timeout, @PreDestroy @PrePassivate() Ready in pool Passive business methods @PostActivate ()
Guidelines for use Coarse-Grained better than Finely-Grained Use stateless whenever possible Use the remote interface for flexibility Guidelines for use Coarse-Grained Business Objects vs. Finely-Grained Business Objects There is some extra overhead associated with using entity beans (locating the object and accessing it) and there over use can effect performance. Entity beans should seldom be used to represent individual table is a database but a broader end users logical view of the data. For example, A Customer Order and all the information contained in the customer order (order information, and line items purchased on order and totals). You would not create an entity bean for each database table involved in the order. Probably not best for doing simple data access like performing simple queries. Entity Java Beans are more complex to create than the data access code to perform a query. Recommendation – Use for logical data objects that are involved in transactions (update, delete or inserting). Do not use for fine grained simple data access, unless, there is some overriding design requirement that would deem only the use of EJBs. For example, the code must be designed to support multiple types of databases such that the databases are interchangeable.
Locating an EJB Must use a directory service and DNS to locate network objects JNDI (Java Naming Directory Interface) Programming interface to the directory services to locate any object in a network (files, EJBs, web services, etc.) EJB’s can be remote anywhere on the network Must use a directory service and DNS to locate network objects JNDI (Java Naming Directory Interface) - java programming interface to DNS It makes easy to access and use the directory services to locate any object in a network files, EJBs, web services, etc.)
Directory Service names Most use X.500 naming standard c (country name) o (organizationName) ou (organizationUnitName) l (localityName) cn (commonName) dc (domainComponent) uid (userid) Each type of directory service has it’s own naming syntax LDAP example cn=Martin Bond, ou=Authors, o=SAMS, c=us Microsoft Active Directory Service cn=Martin Bond/ou=Authors/o=SAMS/c=us
JNDI names JNDI names are not specific to directory services JNDI maps universal name to specific directory service syntax Typical JNDI name “SAMS/authors/Martin Bond”
Outline for using remote EJBs Get initial JNDI naming context Use JNDI to lookup and find EJB Call business function
Defining the JNDI name The JNDI name is best defined in the Session EJB “Bean” class as a constant value. The JNDI name must follow a specific format for the EJB 3.0 architectures. The format is “BeanClassName/remote” where BeanClassName is the name of the class.
Calling business methods try { InitialContext initialContext = new InitialContext(); // get jndi context String jndiName = BusinessRulesBean.RemoteJNDIName; ; // get jndi name // lookup and get remote interface for session bean BusinessRulesRemote businessRulesRemote = (BusinessRulesRemote) initialContext.lookup(jndiName ); // call any business methods defined in the interface Person person = businessRulesRemote.login(username, password); … } catch (NamingException ne) { throw new MyAppException( “Session EJB not found, jndiname=” + jndiName)); catch (Exception e) { throw new MyAppException(ee.getMessage());
Calling business methods try { InitialContext initialContext = new InitialContext(); // get jndi context String jndiName = BusinessRulesBean.RemoteJNDIName; ; // get jndi name // lookup and get remote interface for session bean BusinessRulesRemote businessRulesRemote = (BusinessRulesRemote) initialContext.lookup(jndiName ); // call any business methods defined in the interface Person person = businessRulesRemote.login(username, password); … } catch (NamingException ne) { throw new MyAppException( “Session EJB not found, jndiname=” + jndiName)); catch (Exception e) { throw new MyAppException(ee.getMessage());
Calling business methods try { InitialContext initialContext = new InitialContext(); // get jndi context String jndiName = BusinessRulesBean.RemoteJNDIName; ; // get jndi name // lookup and get remote interface for session bean BusinessRulesRemote businessRulesRemote = (BusinessRulesRemote) initialContext.lookup(jndiName ); // call any business methods defined in the interface Person person = businessRulesRemote.login(username, password); … } catch (NamingException ne) { throw new MyAppException( “Session EJB not found, jndiname=” + jndiName)); catch (Exception e) { throw new MyAppException(ee.getMessage());
Calling business methods try { InitialContext initialContext = new InitialContext(); // get jndi context String jndiName = BusinessRulesBean.RemoteJNDIName; ; // get jndi name // lookup and get remote interface for session bean BusinessRulesRemote businessRulesRemote = (BusinessRulesRemote) initialContext.lookup(jndiName ); // call any business methods defined in the interface Person person = businessRulesRemote.login(username, password); … } catch (NamingException ne) { throw new MyAppException( “Session EJB not found, jndiname=” + jndiName)); catch (Exception e) { throw new MyAppException(ee.getMessage());
Calling business methods try { InitialContext initialContext = new InitialContext(); // get jndi context String jndiName = BusinessRulesBean.RemoteJNDIName; ; // get jndi name // lookup and get remote interface for session bean BusinessRulesRemote businessRulesRemote = (BusinessRulesRemote) initialContext.lookup(jndiName ); // call any business methods defined in the interface Person person = businessRulesRemote.login(username, password); … } catch (NamingException ne) { throw new MyAppException( “Session EJB not found, jndiname=” + jndiName)); catch (Exception e) { throw new MyAppException(e.getMessage());
Insert object into Datastore public void addBranch() { // create a branch java bean Branch branch = new Branch(); branch.setName(“Bank of Nauvoo”); branch.setPhone(“203-356-1426”); // inserts a branch into the database entityManager.persist(branch); }
Update Object in Datastore public void renameBranch(String branchid, String newName) { // get branch by its Primary Key from datastore Branch branch = (Branch) entityManager.find(Branch.class, branchid); // update the branch branch.setBranchname(newName); entityManager.merge(branch); }
Delete Object from Datastore public void deleteBranch(String branchid) { // get branch by its Primary Key from datastore Branch branch = (Branch) entityManager.find(Branch.class, branchid); // Delete the branch entityManager.remove(branch); }
Query Object/s from Datastore public Collection<Branch> getBranches(String name){ // Define query prepared statement String ejbql = "SELECT b FROM Branch b WHERE b.branchname LIKE :branchname”; // Create query object Query query = entityManager.createQuery(ejbql); // Substitute value to search for in prepared statement query.setParameter("branchname", searchValue); // Execute query to get list of branches List<Branch>branches = query.getResultList(); return branches; }
Entity Bean query language (ejb-ql) select_clause from_clause [where_clause] SELECT j FROM Job AS j WHERE j.jobType = ‘web development’ From Examples: SELECT j.* FROM Job AS j WHERE j.jobType = ‘web development’; SQL equivalent:
Entity Bean query language (ejb-ql) select_clause from_clause [where_clause] SELECT s FROM Job AS j, INNER JOIN j.Skills AS s From Examples: SELECT s.* FROM Job AS j INNER JOIN JobSkill AS s ON j.FK_skillID = s.skillID SQL equivalent:
Entity Bean query language (ejb-ql) Inner Joins of Entities Where Examples: SELECT OBJECT o FROM Customer AS c, INNER JOIN c.orders AS o, INNER JOIN o.items AS I WHERE c.lastName = ‘FLINTSTONE” SELECT C.*, O.*, I.* FROM Customer C INNER JOIN Orders O INNER JOIN Items I ON C.customerId = O.FK_CustomerId ON O.FK_ItemId = I.ItemId WHERE C.lastName = ‘FLINSTONE’; SQL equivalent: