ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Business Logic, Part 3
Pages: 1, 2, 3

Finally, don't forget to change your deployment descriptor:

        This AccountManager bean allows administration of Forethought accounts.

All things considered, these are relatively simple changes to make, and have the net effect of making your bean faster, more efficient, and only marginally harder to use.

However, as I mentioned, there are times when the changes to the bean's remote interface are more difficult. Passing in a username or any other piece of data ten, twenty, or more times to a bean's methods can result in pain for the developer, and less-clear code. In these cases, a simple helper class on the client can make a stateless session bean behave just as a stateful one did. Example 8-10 shows this principle in action, detailing the AccountManagerHelper utility class.

Example 8-10: An AccountManager Helper Class

Also in this series:

Business Logic, Part 2
In Part 2 of our excerpt from Chapter 8 of Building Java Enterprise Applications, Vol I: Architecture, Brett McLaughlin builds a UserManager component, and illustrates why managers are a good thing.

Business Logic, Part 1
In this excerpt from Chapter 8 of Building Java Enterprise Applications, Vol I: Architecture, Brett McLaughlin discusses the fašade pattern, in which you use session beans to access entity beans. This access method is used instead of allowing direct access to entity beans, and is key to a sound strategy in building enterprise applications.

package com.forethought.client;
import java.rmi.RemoteException;
import java.util.List;
import javax.ejb.CreateException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
// Account bean
import com.forethought.ejb.account.AccountInfo;
import com.forethought.ejb.account.AccountManager;
import com.forethought.ejb.account.AccountManagerHome;
// AccountType bean
import com.forethought.ejb.accountType.UnknownAccountTypeException;
public class AccountManagerHelper {
    /** The username for this account's user */
    private String username;
    /** The <code>AccountManager</code> bean instance */
    private AccountManager manager;
    public AccountManagerHelper(String username) 
        throws CreateException, NamingException, RemoteException {
        this.username = username;
        Context context = new InitialContext(  );
        // Get the stateless bean instance
        Object ref = context.lookup("forethought.AccountManagerHome");
        AccountManagerHome accountManagerHome = (AccountManagerHome)
            PortableRemoteObject.narrow(ref, AccountManagerHome.class);
        this.manager = accountManagerHome.create(  );
    public AccountInfo add(String type, float balance)
        throws RemoteException, UnknownAccountTypeException {
        return manager.add(username, type, balance);
    public AccountInfo get(int accountId) throws RemoteException {
        return manager.get(accountId);
    public List getAll(  ) throws RemoteException {
        return manager.getAll(username);
    public AccountInfo deposit(AccountInfo accountInfo, float amount)
        throws RemoteException {
        return manager.deposit(accountInfo, amount);
    public AccountInfo withdraw(AccountInfo accountInfo, float amount)
        throws RemoteException {
        return manager.withdraw(accountInfo, amount);
    public boolean delete(int accountId) throws RemoteException {
        return manager.delete(accountId);
    public float getBalance(int accountId) throws RemoteException {
        return manager.getBalance(accountId);

Looking at the methods available on this helper class, you should realize pretty quickly that it mirrors the remote interface of the AccountManager session bean; however, it looks like the stateful bean version, rather than the new stateless version. The constructor for the class then takes the place of the old stateful bean's create( ) method from the home interface. This class then maintains a bean instance, the username for the manager, and delegates to the session bean. All of the same exceptions are passed through to the client, so the interface is very similar; the only difference is that context lookups are handled within the helper class. This makes the client code even simpler, as this code fragment shows:

// Look up the AccountManager bean
System.out.println("Looking up the AccountManager bean.");
AccountManagerHelper accountHelper = 
    new AccountManagerHelper("gqg10012");
// Create an account
AccountInfo everydayAccount = accountHelper.add("Everyday", 5000);
if (everydayAccount == null) {
    System.out.println("Failed to add account.\n");
System.out.println("Added account.\n");
// Get all accounts
List accounts = accountHelper.getAll(  );
for (Iterator  i = accounts.iterator(); i.hasNext(  ); ) {
    AccountInfo accountInfo = (AccountInfo)i.next(  );
    System.out.println("Account ID: " + accountInfo.getId(  ));
    System.out.println("Account Type: " + accountInfo.getType(  ));
    System.out.println("Account Balance: " + 
        accountInfo.getBalance(  ) + "\n");
// Deposit
accountHelper.deposit(everydayAccount, 2700);
System.out.println("New balance in everyday account: " +
    accountHelper.getBalance(everydayAccount.getId(  )) + "\n");
// Withdraw
accountHelper.withdraw(everydayAccount, 500);
System.out.println("New balance in everyday account: " +
    accountHelper.getBalance(everydayAccount.getId(  )) + "\n");
// Delete account
accountHelper.delete(everydayAccount.getId(  ));
System.out.println("Deleted everyday account.");

You may find that helper classes like this can simplify your own client code, even if you don't need to provide stateful session bean masquerading, where a stateless bean is made to look like a stateful one. In any case, this approach provides the best of both session bean types: the performance of a stateless bean with the interface of a stateful one. This technique will allow you to convert all of your application's stateful session beans into stateless ones, which will yield some dramatic performance improvements.

What's Next?

You now have the tools to build the back-end of almost any enterprise application you may come across, and apply your knowledge to most of the problems you will encounter in the enterprise Java space. In the next chapter, though, I want to move beyond the basics into the less-used realm of the Java Message Service (and specifically, message-driven beans). Although it is still somewhat unusual to see these kinds of beans in action, you will find that JMS offers several attractive features. I'll detail these and how they can help in asynchronous tasks in the next chapter, which focuses specifically on messaging in enterprise applications.

Brett McLaughlin had developed enterprise Java applications for Nextel Communications and Allegiance Telecom. When that became fairly mundane, Brett took on application servers. He then got hooked on open source software, and helped found several cool programming tools, like Jakarta turbine and JDOM.

View catalog information for Building Java Enterprise Applications Vol I: Architecture

Return to ONJava.com.