Business Logic, Part 3

Business Logic, Part 3


Example 8-9: The AccountManager Implementation Class

package com.forethought.ejb.account;

 

import java.rmi.RemoteException;

import java.util.Collection;

import java.util.Iterator;

import java.util.LinkedList;

import java.util.List;

import javax.ejb.CreateException;

import javax.ejb.FinderException;

import javax.ejb.EJBHome;

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.naming.NamingException;

 

import com.forethought.ejb.util.SessionAdapter;

 

// Account bean

import com.forethought.ejb.account.Account;

import com.forethought.ejb.account.AccountHome;

import com.forethought.ejb.account.AccountInfo;

 

// AccountType bean

import com.forethought.ejb.accountType.UnknownAccountTypeException;

 

// User bean

import com.forethought.ejb.user.User;

import com.forethought.ejb.user.UserHome;

 

// LDAPManager (for utility method)

import com.forethought.ldap.LDAPManager;

 

public class AccountManagerBean extends SessionAdapter {

    

    /** Username related to this account */

    private String username;

    

    /** User bean for this account's user */

    private User user;

    

    /** <p> Required method for allowing bean lookups. </p> */

    public void ejbCreate(String username) 

        throws CreateException, RemoteException {

            

        this.username = username;

        

        try {

            // Get an InitialContext

            Context context = new InitialContext(  );

 

            // Look up the Account bean

            UserHome userHome = (UserHome) 

                context.lookup("java:comp/env/ejb/UserHome");

            this.user = userHome.findByUserDn(LDAPManager.getUserDN(username));

        } catch (NamingException e) {

            throw new CreateException("Could not load underlying User bean.");

        } catch (FinderException e) {

            throw new CreateException("Could not locate specified user.");

        }

    }

    

    public AccountInfo add(String type, float balance)

        throws UnknownAccountTypeException {

     

        try {

            // Get an InitialContext

            Context context = new InitialContext(  );

 

            // Look up the Account bean

            AccountHome accountHome = (AccountHome) 

                context.lookup("java:comp/env/ejb/AccountHome");

            Account account = accountHome.create(type, balance, user);

            return account.getInfo(  );

        } catch (RemoteException e) {

            return null;

        } catch (CreateException e) {

            return null;

        } catch (NamingException e) {

            return null;

        }

    }

 

    public AccountInfo get(int accountId) throws RemoteException {

        return getAccount(accountId).getInfo(  );

    }

 

    public List getAll(  ) {

        List accounts = new LinkedList(  );

        

        try {

            Integer userId = user.getId(  );

            

            // Get an InitialContext

            Context context = new InitialContext(  );

 

            // Look up the Account bean

            AccountHome accountHome = (AccountHome) 

                context.lookup("java:comp/env/ejb/AccountHome");

            Collection userAccounts = accountHome.findByUserId(userId);

            for (Iterator i = userAccounts.iterator(); i.hasNext(  ); ) {

                Account account = (Account)i.next(  );

                accounts.add(account.getInfo(  ));

            }

        } catch (Exception e) {

            // Let fall through to the return statement

        }

        return accounts;

    }

 

    public AccountInfo deposit(AccountInfo accountInfo, float amount) 

        throws RemoteException {

            

        // Look up bean, to ensure most current view of data

        Account account = getAccount(accountInfo.getId(  ));

        AccountInfo info = account.getInfo(  );

        

        // Update balance

        info.setBalance(info.getBalance(  ) + amount);

        try {

            account.setInfo(info);

        } catch (UnknownAccountTypeException neverHappens) { }

        return info;

    }

 

    public AccountInfo withdraw(AccountInfo accountInfo, float amount)

        throws RemoteException {

            

        // Look up bean, to ensure most current view of data

        Account account = getAccount(accountInfo.getId(  ));

        AccountInfo info = account.getInfo(  );

        

        // Update balance

        info.setBalance(info.getBalance(  ) - amount);

        try {

            account.setInfo(info);

        } catch (UnknownAccountTypeException neverHappens) { }

        return info;

    }

    

    public boolean delete(int accountId) {

        try {

            Account account = getAccount(accountId);

            account.remove(  );

            return true;

        } catch (Exception e) {

            return false;

        }

    }

 

    public float getBalance(int accountId) throws RemoteException {

        return getAccount(accountId).getBalance(  );

    }

 

    private Account getAccount(int id) {

	

            // Get an InitialContext

            Context context = new InitialContext(  );

 

            // Look up the Account bean

            AccountHome accountHome = (AccountHome) 

                context.lookup("java:comp/env/ejb/AccountHome");

            Account account = accountHome.findByPrimaryKey(new Integer(id));

            

            return account;

        } catch (Exception e) {

            // Any problems - just return null

            return null;

        }

    }

}

This is all basic EJB material, and shouldn't cause you any problems. You'll notice that this class also uses a new finder method on the Account bean:

public Collection findByUserId(Integer userId)

    throws FinderException, RemoteException;

The accompanying query element in the Account bean's entry in the ejb-jar.xml descriptor would look like this:

<query>

  <query-method>

    <method-name>findByUserId</method-name>

    <method-params>

      <method-param>java.lang.Integer</method-param>

    </method-params>

  </query-method>

  <ejb-ql>

    <![CDATA[WHERE userLocal.id = ?1]]>

  </ejb-ql>

</query>

To deploy the AccountManager bean, you would use this (additional) XML entry in your ejb-jar.xml deployment descriptor:

<session>

  <description>

    This AccountManager bean allows administration of Forethought accounts.

  </description>

  <ejb-name>AccountManagerBean</ejb-name>

  <home>com.forethought.ejb.account.AccountManagerHome</home>

  <remote>com.forethought.ejb.account.AccountManager</remote>

  <ejb-class>com.forethought.ejb.account.AccountManagerBean</ejb-class>

  <session-type>Stateful</session-type>

  <transaction-type>Container</transaction-type>

  <ejb-ref>

    <ejb-ref-name>ejb/AccountHome</ejb-ref-name>

    <ejb-ref-type>Entity</ejb-ref-type>

    <home>com.forethought.ejb.account.AccountHome</home>

    <remote>com.forethought.ejb.account.Account</remote>

    <ejb-link>AccountBean</ejb-link>

  </ejb-ref>

</session>

Additions to your application server's vendor-specific descriptors should be equally simple. With this bean in stateful form ready for use, it's time to see how it can be turned into a better-performing stateless session bean.

Going Stateless

To move this bean into stateless territory, you first need to change the home interface's create( ) signature. Since stateless beans can't maintain any information between method calls, passing in a username (or any other data) to the create( ) method is useless. Make the following change:

    public AccountManager create(  ) 

        throws CreateException, RemoteException;

Once this is done, you will need to determine which methods advertised by the bean require a username for operation. In other words, browse through your bean's implementation class and note any method that uses the username or user method variable. Once you've determined the methods in this category, you will need to change the signature for those methods in the remote interface:

public interface AccountManager extends EJBObject {

 

    public AccountInfo add(String username, String type, float balance)

        throws RemoteException, UnknownAccountTypeException;

        

    public AccountInfo get(int accountId) throws RemoteException;

    

    public List getAll(String username) throws RemoteException;

    

    public AccountInfo deposit(AccountInfo accountInfo, float amount)

        throws RemoteException;

        

    public AccountInfo withdraw(AccountInfo accountInfo, float amount)

        throws RemoteException;

        

    public float getBalance(int accountId) throws RemoteException;

 

    public boolean delete(int accountId) throws RemoteException;  

}

In this case, only two methods require this information, so it's not terribly inconvenient. However, in many cases conversion from stateful to stateless requires a parameter to be added to ten, twenty, or more methods. Even though this example is somewhat trivial, I want to continue the discussion assuming that it is a major issue to have to keep the username around for these multiple method calls. Before getting to the solution, though, you'll need to update your bean implementation class to operate without maintaining state. First, add a utility method to the end of the class:

private User getUser(String username) throws RemoteException {

    try {

        // Get an InitialContext

        Context context = new InitialContext(  );

 

        // Look up the Account bean

        UserHome userHome = (UserHome) 

            context.lookup("java:comp/env/ejb/UserHome");

        User user = userHome.findByUserDn(LDAPManager.getUserDN(username));

        return user;

    } catch (NamingException e) {

        throw new RemoteException("Could not load underlying User bean.");

    } catch (FinderException e) {

        throw new RemoteException("Could not locate specified user.");

    }

}

Then remove the username and user member variables, and modify three methods (those affected by the change to stateless):

public void ejbCreate(  ) throws CreateException {

    // Nothing to be done for stateless beans

}

 

public AccountInfo add(String username, String type, float balance)

    throws UnknownAccountTypeException {

  

    try {

        // Get an InitialContext

        Context context = new InitialContext(  );

        

        // Get the correct user

        User user = getUser(username);

 

        // Look up the Account bean

        AccountHome accountHome = (AccountHome) 

            context.lookup("java:comp/env/ejb/AccountHome");

        Account account = accountHome.create(type, balance, user);

        return account.getInfo(  );

    } catch (RemoteException e) {

        return null;

    } catch (CreateException e) {

        return null;

    } catch (NamingException e) {

        return null;

    }

}

 

public List getAll(String username) {

    List accounts = new LinkedList(  );

    

    try {

        User user = getUser(username);

        Integer userId = user.getId(  );

        

        // Get an InitialContext

        Context context = new InitialContext(  );

 

        // Look up the Account bean

        AccountHome accountHome = (AccountHome) 

            context.lookup("java:comp/env/ejb/AccountHome");

        Collection userAccounts = accountHome.findByUserId(userId);

        for (Iterator i = userAccounts.iterator(); i.hasNext(  ); ) {

            Account account = (Account)i.next(  );

            accounts.add(account.getInfo(  ));

        }

    } catch (Exception e) {

        // Let fall through to the return statement

    }

    return accounts;

}

Prev  [1] [2] [3] Next

Close    To Top
  • Prev Article-Java:
  • Next Article-Java:
  • Now: Tutorial for Web and Software Design > Java > JavaBeans > Java Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction