Discussions

EJB design: Can Business delegate be a SessionBean ?

  1. Can Business delegate be a SessionBean ? (8 messages)

    Hi all,

    I have a set of session beans which can be accessed thru business delegates(normal Java classes).

    How to access a business delegate being a normal java class from a remote client, if I'm not interested to give direct access to my beans ?

    Will it be a good solution to change the business delegates from normal java classes to session beans, or will it complicate the situation ?

    Any suggestions or opinions are appreciated..

    Thanks
    Viji
  2. Hello Viji,
    Business Delegate Decoples Presentation and Business Logic. This is a normal Java Class and not a session Bean. When you go for Session Bean you have to create Remote Interface for that, which makes it again coupled with business logic.
    Now in case of Business Delegate as Java class which generally resides on webserver helps java Clients to be totatly independent. BD accesses Home interface of say Session Bean through Service Locator and then it gets remote reference to bean to call Business Methods. Since BD is on webserver that call is not remote call for a client and hence there is no problem in accessing BD and BD makes remote call to beans and decouples Presentation and Business Logic.
    So changing BD to Session bean will definetly complicate the situation
    I hope this answers your question.
    Regards
    Raj
  3. How to access a business delegate being a normal java class from a remote >client, if I'm not interested to give direct access to my beans ?


    I guess RMI will be a simple option. but again what you are doing is trying to develop a framework which is already supported by session beans. If you have problem in giving direct access to session beans (which is like kind of puzzle to me, why not). Then you can use some authentication for finding out if the call is comming from trusted user.

    > Will it be a good solution to change the business delegates from normal java >classes to session beans, or will it complicate the situation ?

    I guess it will be best thing to change normal java class to session bean. that way you will get all advangates of J2EE technology.

    Here is a reflection implementation to convert normal java class to enterprise bean class

    Brewing Entity Enterprise JavaBeans
    Harness the power of entity beans
    by Sandip H. Mandera; Reprinted from JavaWorld
    The Enterprise JavaBeansTM (EJBTM) specification provides two flavors of beans: session beans and entity beans. After Sun Microsystems's release of EJB Specification 1.1, support for entity beans became mandatory. This article will introduce component developers to entity beans and show how to channel the beans' power.
    Enterprise JavaBeans (EJB) represents a fundamental change in the world of enterprise software. The EJB specification provides the software development community with the component model, maintains interoperability between EJB and non-EJB applications (including non-Java-based applications like CORBA), and features straightforward programming. The power of EJB resides in the fact that it saves a developer the pain of developing a homegrown infrastructure.
    This article will focus on the design and development of container-managed entity beans. I will begin with a brief summary of the changes introduced in EJB Specification 1.1 and follow it with a brief tour of session beans before I delve fully into a discussion of entity beans (the fun part).
    Improved Recipe
    EJB Specification 1.1 tightened some of the issues that were loosely defined by Sun Microsystems in version 1.0. These are the changes/modifications, as defined by EJB Specification 1.1:
    1. Mandatory entity-bean support for container providers.
    2. Improved support for EJB environment management, which means the bean provider must specify the bean's entire environment using entries in a JNDITM context.
    3. Clear lines of separation between the roles and responsibilities of the bean provider and that of the application assembler.
    4. Removed support of deployment descriptor features that described the deployer's output. Also, the deployment descriptor is specified in XML.
    5. JDKTM 1.2 caused the EJB container vendors to change their runtime libraries with the Java class java.security.Identity to java.security.Principal interface.
    6. The package name of the javax.jts interface has changed to javax.transaction. Also, modifications were made in the thrown exceptions.
    7. All finder methods must throw the FinderException.
    8. ejbCreate() requires a different value. Instead of void(), ejbCreate() returns the primary key class reference.
    As a component developer, you must understand what each bean flavor provides its clients. EJB Specification 1.1 supports both session and entity beans. Before we brew the beans, let's taste each flavor.
    Taste Session Beans
    Before tasting the session beans, we must first understand their main ingredient: their sessions. A session represents a conversation instance. And like any conversation, a session exists for a limited period of time. It ends when the thread connecting the conversation dies.
    A session bean is a logical extension of the conversation instance, but resides on the server. For its entire life, a session bean exists in the container, which manages security, concurrency, etc. Also, the client view of a session bean does not depend upon location. A session bean presents the same set of APIs to its client, which can be another EJB, a Java applet, a Java application, a Java servlet, or a CORBA client. Whether the client runs in the same Java VM as the session bean is immaterial.
    Unlike entity beans (which I will discuss later), session beans do not advertise their identities. Thus, session beans appear to be anonymous to the client. Because of this, when EJBObject.getPrimaryKey() and EjbHome.remove(Object primaryKey) methods are invoked on session beans, you obtain java.rmi.RemoteException. This means component developers should not provide finder methods when writing session beans.
    Also, single-client applications (I use the word application loosely) use session beans, which are relatively short-lived and unable to survive an application crash or server restart.
    Now that we have tasted session beans, let's savor the power of entity beans.
    Taste Entity Beans
    An entity bean represents a component view of the data residing in a persistent storage area, like a database or a flat file. You would usually map a row in a database to an entity bean. For instance, let's say the following employee table resides in a database with the following schema:
       Employee_ID:SMALLINT
       Employee_Name:VARCHAR(50)
       Employee_Address:VARCHAR(50)
    The component developer would create an entity bean called EmployeeBean that contained the three attributes present in the employee table. Like session beans, entity beans are server-side components and live within a container. However, unlike session beans, entity beans can endure a server restart or container crash. Also, the container provides various services like security, concurrency, transaction management, and persistence -- in the case of container-managed entity beans.
    Different clients can concurrently access each entity bean. The container manages the underlying synchronization of the entity beans' data in a container-managed persistence. In a bean-managed persistence, you must write code to ensure consistent data management. Like session beans, every entity bean offers the same view to its client, irrespective of whether the client runs in the same Java VM. Also like session beans, an entity bean's client can be another bean, a Java applet, a Java application, Java servlet, or even a CORBA client.
    A container can manage multiple entity beans deployed within it, and provides a home interface for each deployed bean. An entity bean's home interface provides the bean's client with a set of APIs to create, find, and remove entity bean instances. To create entity bean components, you must implement the following two interfaces over and above the component (i.e. the bean):
    1. The home interface: EJBHome
    2. The remote interface: EJBRemote
    Home Interface
    The entity bean developer creates a home interface, which inherits the javax.ejb.EJBHome interface. Let's look at javax.ejb.EJBHome and the methods an entity bean would have in its home interface:
    public interface EJBHome extends Remote
    {
      void remove(Handle someHandle) throws RemoteException, RemoveException;
      void remove(Object aPrimaryKey) throws RemoteException, RemoveException;
    }
    The methods an entity bean would have on its home interface are:
    · Create Methods
    Unlike session beans, the EJB specification allows for overloaded create() methods to create entity beans. Typically, you would pass data as arguments to this method; you could then initialize the entity bean with the needed state when it is created. The specification mandates that the return type of the create() method return a reference to the EJBRemote object. Also, the throws clause of every create() method should have java.rmi.RemoteException and javax.ejb.CreateException. However, you have the flexibility to add any application-specific exceptions to the throws clause.
    · Finder Methods
    An entity bean's home interface defines one or more finder methods. EJB Specification 1.1 tells you to provide the findByPrimaryKey() method for entity beans. This method allows a client to look up entity beans by their primary key. The name findByPrimaryKey() must not change, and it should provide one argument that represents the entity bean's primary key type. The return type of findByPrimaryKey() must be an entity bean's remote interface. Each finder method should throw java.rmi.RemoteException and javax.ejb.FinderException. If you want to provide your own custom finder methods, the specification allows for other methods in addition to findByPrimaryKey().
    · Remove Methods
    The EJBHome interface provides several ways for a client application to remove an entity bean object that a client is interacting with. A client attempting to use an entity bean that has been removed would get java.rmi.NoSuchObjectException.
    Now that we have covered some basics, let's look at the primary key and object identity of an entity bean.
    The component developer creates a primary key class for each entity bean. Hence, if two entity objects have the same home interface and primary key, they are considered identical. The EJB specification does not mention object equality based on the = = operator. Also, if you compare two object references using the Java API, Object.equals(Object foo), the result is unspecified. The only way to compare object equality is through the isIdentical(EJBObject) API.
    According to the EJB Specification 1.1, a primary key class is any class with a legal value type in RMI-IIOP. Generally, a primary key class would be associated with a particular entity bean class. However, you are free to use the same primary key class for multiple entity beans.
    Now let's see how the employee entity bean home interface and its corresponding PrimaryKey class might look.
       ////////////////////////////////////////////////
       // Employee Entity Bean Home Interface
       ////////////////////////////////////////////////

       package com.mandera.entitybeansarticle;

       import javax.ejb.EJBHome;
       import java.ejb.CreateException;
       import java.ejb.FinderException;
       import java.ejb.RemoteException;

       public interface EmployeeHome extends EJBHome
       {
     public Employee create(int employeeID, String name, String address)
          throws CreateException, RemoteException;
     public Employee findByPrimaryKey(EmployeePrimaryKey empKey)
        throws FinderException, RemoteException;
       }

       ////////////////////////////////////////////
       // Primary Key Class
       ////////////////////////////////////////////
       package com.mandera.entitybeansarticle;
       public class EmployeePrimaryKey implements java.io.Serializable
       {
     public int employeeId;
       }
    The EJB specification requires that the instance of PrimaryKey be serializable.
    The Remote Interface
    The entity bean's client accesses the entity bean object through its remote interface, which provides the client with a set of business methods. An entity bean's remote interface must extend the java.ejb.EJBObject interface.
    The following example illustrates the use of remote interface:
       //////////////////////////////////////////////
       // Employee Entity Bean Remote Interface
       //////////////////////////////////////////////

       package com.mandera.entitybeansarticle;

       import javax.ejb.EJBObject;
       import java.ejb.RemoteException;

       public interface Employee extends EJBObject
       {
         public int getEmployeeID() throws RemoteException;
         public void setEmployeeName(String empName) throws RemoteException;
         public String getEmployeeName() throws RemoteException;
         public void setEmployeeAddress(String address) throws RemoteException;
         public String getEmployeeAddress() throws RemoteException;

       }
    Persist an Entity Bean
    EJB Specification 1.1 provides two ways to persist an entity bean: container-managed persistence (a relatively simple technique) and bean-managed persistence.
    Container-managed persistence
    When using container-managed persistence, the component developer is relieved of writing code to provide a persistence mechanism. The EJB container provider takes on the responsibility instead. However, at the time of deployment, the deployer must give the EJB container's tool a list of fields that must be persisted. In turn, the EJB container generates the corresponding database access calls. The advantage of this approach is that the entity bean is hidden from the type of data storage mechanism. The disadvantage is that the EJB container and its tools must be sophisticated enough to map the entity bean's fields to data sources during the deployment stage. For instance, if you use a relational database, the container must be able to undertake object-to-relational mapping.
    Bean-managed persistence
    When using bean-managed persistence, the component provider shoulders the responsibility of writing database access calls. From a design perspective, the database access calls can be programmed within the entity bean or can reside in another component, thus encapsulating the entity bean from the persistence mechanism. Because it increases software extensibility, I prefer encapsulating the persistence mechanism in different components rather than within the entity bean. This approach makes it easier for an entity bean to work with any other database or a database with a different schema.
    Let's look at sample code for an entity bean with container-managed persistence:
       ////////////////////////////////////////////
       // Employee Entity Bean: Container Managed
       ////////////////////////////////////////////

       package com.mandera.entitybeansarticle;

       import javax.ejb.EntityBean;
       import java.ejb.EntityContext;
       import java.ejb.CreateException;

       public class EmployeeBean implements EntityBean
       {
         private transient EntityContext entContext;

         public int employeeID;
         public String employeeName;
         public String employeeAddress;

         public void setEntityContext(EntityContext context)
         {
           entContext = context;
         }

         public void unsetEntityContext()
         {
           entContext = null;
         }

         public EmployeePrimaryKey ejbCreate(int ID, String name, String
    address)
                                   throws CreateException
         {
            employeeID = ID;
            employeeName = name;
            employeeAddress = address;
            return null;

         }

         public void ejbPostCreate(int ID, String name, String address)
                                  throws CreateException
        {
        }

        public void ejbActivate()
        {

        }

        public void ejbPassivate()
        {

        }

        public void ejbRemove()
        {

        }

        public void ejbLoad()
        {
        }

        public void ejbStore()
        {
        }

        public int getEmployeeID()
        {
           return this. employeeID;
        }

        public void setEmployeeName(String empName)
        {
           employeeName = empName;
        }

        public String getEmployeeName()
        {
           return this.employeeName;
        }

       public void setEmployeeAddress(String address)
       {
          employeeAddress = address;
       }

       public String getEmployeeAddress()
       {
          return this.employeeAddress;
       }


       }
    Now, let's examine the significance of each of these methods in the context -- no pun intended -- of the entity beans:
    1. setEntityContext(EntityContext context): The container invokes this method to pass a reference of the EntityContext interface to the instance of an entity bean. In order to use the EntityContext interface during its lifetime, the entity bean must save the state of the EntityContext interface in its instance variable.
    2. unsetEntityContext(): The container invokes this method before terminating the entity bean instance, which can take advantage of this method to free any resources it had previously created.
    3. ejbCreate(): An entity bean can have zero or more ejbCreate() methods. However, the signature of each one should map to the create() methods in the entity bean home interface. When a client of the component invokes a create() method to create a component, the container invokes the appropriate ejbCreate() method. You might be wondering why in the above example, even though I have said that the return type of the ejbCreate() method should be an entity bean's primary key class instance, I return a null value. This is not a programming mistake -- in fact, in the case of container-managed persistence, the container knows this and actually ignores the null value.
    With this programming model, if you decide to inherit another entity bean with bean-managed persistence from a bean with container-managed persistence -- even though you would override the method in your subclass -- the API would still hold true, since the signature would be the same. Upon execution of the ejbCreate() method, the container would insert the data into the database. This method cannot be declared as final or static.
    4. ejbPostCreate(): For each ejbCreate() method, you provide a set of matched ejbPostCreate() methods with a void return type. When the container invokes ejbCreate(), it immediately calls the corresponding ejbPostCreate() method on the instance of the entity bean. As a component developer, you can use the ejbPostCreate() method to undertake any special purpose-processing for the bean before it becomes available to its client. In our example above, we did not have any need for special purpose processing, and therefore decided to provide only skeletal implementation. It is important to provide at least a skeletal implementation; the EJB container expects it to be there. Also, like ejbCreate(), this method cannot be declared final or static.
    5. ejbActivate(): The EJB container invokes this method when an entity bean instance is loaded from the pool and assigned a specific object identity (OID). This method lets the entity bean, while in ready state, procure any additional resources it has not yet acquired.
    6. ejbPassivate(): This method is a counterpart of ejbActivate(). The EJB container invokes this API on the entity bean instance when the EJB container decides to return it to the bean pool. This method allows the entity bean instance to release any resources it should not hold while in the pool. In other words, if you create any resources during the ejbActivate() method, you should free them in this method.
    7. ejbRemove(): When the entity bean's client invokes remove() on its home interface, the container invokes ejbRemove(). After this method successfully completes, the container returns the entity bean instance to the bean pool. The container synchronizes the bean's state before calling the ejbRemove() method. Since the state of the bean instance at the end of this method must be equivalent to its passive state, the instance would release any resources acquired during the ejbActivate() method.
    8. ejbLoad() and ejbStore(): When in ready state in the bean pool, an entity bean must keep its state synchronous with the underlying data. During the call to the ejbLoad() method, the data is read from the database and the instance variables are updated accordingly. Similarly, calling the ejbStore() method results in its writing the entity bean state to the database.
    Summary
    The entity bean component provider is responsible for providing the following set of classes:
    · Entity bean's home interface
    · Entity bean's remote interface
    · Entity bean class and any helper classes associated with it
    · Primary key class
    The entity bean class must implement the javax.ejb.EntityBean interface. The class must be defined as public and cannot be abstract. All the instance variables of a container-managed entity bean must be declared public, so the container can access those variables. The entity bean class cannot be declared abstract or final. It cannot define the finalize() method. The entity bean must implement the business methods, ejbCreate(), ejbPostCreate(), ejbLoad(), ejbStore(), and ejbFindByPrimaryKey() methods.
    Conclusion
    This article focuses on the changes introduced by Sun Microsystems in its EJB Specification 1.1, and is directed at a component developer interested in designing and developing container-managed entity beans. It provides an understanding of the key concepts behind container-managed persistence and the significance of various APIs in the EJB realm. Hopefully, this article taught you to apply these concepts in developing real-world applications and leverage the power of Enterprise JavaBeans. The EJB container will relieve you of the everyday frustrations associated with supporting homegrown infrastructure services like security, transaction management, and persistence.
     
    About the author
    Sandip H. Mandera holds a master's degree in computer science and engineering from the University of Texas at Arlington and a bachelor's in electrical and electronics engineering from Regional Engineering College in Calicut, India. He has worked in the software engineering field for over five years. He enjoys designing and developing software using object-oriented techniques.
    Reprinted with permission from JavaWorld (September 2000). Copyright ITworld.com, Inc., an IDG company. Register for editorial e-mail alerts.
  4. Using Normal Java Classes for BD[ Go to top ]

    Hi Chetan,
    BDs are normal java classes because they reduce remote calls and complexities involved in bean creation and lookup in distributed invironment. If you make BD as Session bean, then you will have to access this bean through remote reference which is definetly a bad idea as you are increasing the complexity of the System. If you check the Context of the BD is says "A multi-tiered, distributed system requires remote method invocations to send and receive data across tiers. Clients are exposed to the complexity of dealing with distributed components."
    So accourding to best practices I suggest it <bold>should be</bold> a java class and not a session Bean
  5. In reply to Mr.Raj,
    Thanks for your response. I do understand that inorder to avoid the coupling between presentation and business logic,we introduce business delegates(BD).

    But my concern is, how to remote clients access my beans thru BDs ? Since these BDs are java classes, they are not bound to the container and I cannot refer this like a bean(container knows about it)...That's my concern.. This is a very practical problem I face now. That's the reson why I was thinking about chaning BDs to session beans again, so that it is easy to have remote access to the beans.

    In Reply to Mr.Chetan,
    Thanks for taking time to answer my question. Unfortunately, ur response seems to be exclusively for entity beans. I'm bothered very much about my session beans not entity...Thanks anyway..
  6. Guys:

       I pasted that code so that you will get a rough idea and modify it for your session bean. Any way that apart. Coming back to Business Delegates.

       I have simple question for both of you, if you are planning to somehow access these simple java classes through remote client, what will be the behavior on multiple client calls. Secondly will there be any security issue involved? How are you planning to take care of transactions?

       If I am not wrong you can refer to session facade pattern available on same site in books section ejb patterns book. Generally the approach is to use session facade and put ur Business delegate simple java classes as helper classes for your session beans. In tern the session bean uses entity bean and connects to persistence layer.

       If you are worried about model view controller stuff .. Then I will say your BD shall sit in controller layer and shall not have any worries of model or view. Define a simple servlet, which will open you to n number of client and later delegate your request to respective BD session beans.

    Hope this helps in solving your problem
    My suggestion will be to refer EJB patterns book available on this site.
    Regards
    Chetan
  7. Can Business delegate be a SessionBean ?[ Go to top ]

    Hello Viji,
    The BusinessDelegate uses a LookupService for locating the business service. So Even if you are using Fat client it doesn't matter. That BD calls LookupService and gets reference to beans or rather Business Service.
    If I correctly understand your question, I think you want to know how Fat clients on remote machine can access the Session beans?
    The answer will be BD can be implemented using RMI-IIOP. The name in this case can be different than Business Delegate!!!
    I hope this answers the question
    Raj
  8. Can Business delegate be a SessionBean ?[ Go to top ]

    An alternative would be to create a servlet that uses the BusinessDelegate and interface the client with the servlet. This way you could use http instead of RMI-IIOP, Corba or some other networking protocol.
  9. Can Business delegate be a SessionBean ?[ Go to top ]

    Hi John,
    This suggession works fine with Applet to Servlet Communication. But if you want to use Applications and want to connect Distributed J2EE components, then RMI-IIOP is a good option.

    Raj