Download PDF Home History |  | API Search Feedback FAQ

> ## Method Invocations in RosterApp

> To show how the various components interact, this section describes the sequence of method invocations that occur for particular functions. The source code for the components is in the `<``INSTALL``>/j2eetutorial14/examples/ejb/cmproster` directory.

> ### Creating a Player

> #### 1. RosterClient

> The `RosterClient` invokes the `createPlayer` business method of the `RosterBean` session bean to create a new player. In the following line of code, the type of the `myRoster` object is `Roster`, the remote interface of `RosterBean`. The argument of the `createPlayer` method is a `PlayerDetails` object, which encapsulates information about a particular player.

>     myRoster.createPlayer(new PlayerDetails("P1", "Phil Jones",
>       "goalkeeper", 100.00));

> #### 2. RosterBean

> The `createPlayer` method of the `RosterBean` session bean creates a new instance of the `PlayerBean` entity bean. Because the access of `PlayerBean` is local, the `create` method is defined in the local home interface, `LocalPlayerHome`. The type of the `playerHome` object is `LocalPlayerHome`. Here is the source code for the `createPlayer` method:

>     public void createPlayer(PlayerDetails details) {

>     try {
>       LocalPlayer player = playerHome.create(details.getId(),
>         details.getName(), details.getPosition(),
>           details.getSalary());
>     } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }
>     }

> #### 3. PlayerBean

> The `ejbCreate` method assigns the input arguments to the bean's persistent fields by calling the `set` access methods. At the end of the transaction that contains the create call, the container saves the persistent fields in the database by issuing an SQL `INSERT` statement. The code for the `ejbCreate` method follows.

>     public String ejbCreate (String id, String name,
>       String position, double salary) throws CreateException {

>       setPlayerId(id);
>       setName(name);
>       setPosition(position);
>       setSalary(salary);
>       return null;
>     }

> ### Adding a Player to a Team

> #### 1. RosterClient

> The `RosterClient` calls the `addPlayer` business method of the `RosterBean` session bean to add player P1 to team T1. The `P1` and `T1` parameters are the primary keys of the `PlayerBean` and `TeamBean` instances, respectively.

>      myRoster.addPlayer("P1", "T1");

> #### 2. RosterBean

> The `addPlayer` method performs two steps. First, it calls `findByPrimaryKey` to locate the `PlayerBean` and `TeamBean` instances. Second, it invokes the `addPlayer` business method of the `TeamBean` entity bean. Here is the source code for the `addPlayer` method of the `RosterBean` session bean:

>     public void addPlayer(String playerId, String teamId) {

>       try {
>         LocalTeam team = teamHome.findByPrimaryKey(teamId);
>         LocalPlayer player =
>           playerHome.findByPrimaryKey(playerId);
>         team.addPlayer(player);
>       } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }
>     }

> #### 3. TeamBean

> The `TeamBean` entity bean has a relationship field named `players`, a `Collection` that represents the players that belong to the team. The access methods for the `players` relationship field are as follows:

>     public abstract Collection getPlayers();
>     public abstract void setPlayers(Collection players);

> The `addPlayer` method of `TeamBean` invokes the `getPlayers` access method to fetch the `Collection` of related `LocalPlayer` objects. Next, the `addPlayer` method invokes the `add` method of the `Collection` interface. Here is the source code for the `addPlayer` method:

>     public void addPlayer(LocalPlayer player) {
>       try {
>         Collection players = getPlayers();
>         players.add(player);
>       } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }
>     }

> ### Removing a Player

> #### 1. RosterClient

> To remove player `P4`, the client would invoke the `removePlayer` method of the `RosterBean` session bean:

>     myRoster.removePlayer("P4");

> #### 2. RosterBean

> The `removePlayer` method locates the `PlayerBean` instance by calling `findBy-PrimaryKey` and then invokes the `remove` method on the instance. This invocation signals the container to delete the row in the database that corresponds to the `PlayerBean` instance. The container also removes the item for this instance from the `players` relationship field in the `TeamBean` entity bean. By this removal, the container automatically updates the `TeamBean-PlayerBean` relationship. Here is the `removePlayer` method of the `RosterBean` session bean:

>     public void removePlayer(String playerId) {
>       try {
>         LocalPlayer player =
>           playerHome.findByPrimaryKey(playerId);
>         player.remove();
>       } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }
>     }

> ### Dropping a Player from a Team

> #### 1. RosterClient

> To drop player `P2` from team `T1`, the client would call the `dropPlayer` method of the `RosterBean` session bean:

>     myRoster.dropPlayer("P2", "T1");

> #### 2. RosterBean

> The `dropPlayer` method retrieves the `PlayerBean` and `TeamBean` instances by calling their `findByPrimaryKey` methods. Next, it invokes the `dropPlayer` business method of the `TeamBean` entity bean. The `dropPlayer` method of the `RosterBean` session bean follows:

>     public void dropPlayer(String playerId, String teamId) {

>       try {
>         LocalPlayer player =
>           playerHome.findByPrimaryKey(playerId);
>         LocalTeam team = teamHome.findByPrimaryKey(teamId);
>         team.dropPlayer(player);
>       } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }
>     }

> #### 3. TeamBean

> The `dropPlayer` method updates the `TeamBean-PlayerBean` relationship. First, the method retrieves the `Collection` of `LocalPlayer` objects that correspond to the `players` relationship field. Next, it drops the target `player` by calling the `remove` method of the `Collection` interface. Here is the `dropPlayer` method of the `TeamBean` entity bean:

>     public void dropPlayer(LocalPlayer player) {

>       try {
>         Collection players = getPlayers();
>         players.remove(player);
>       } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }
>     }

> ### Getting the Players of a Team

> #### 1. RosterClient

> The client can fetch a team's players by calling the `getPlayersOfTeam` method of the `RosterBean` session bean. This method returns an `ArrayList` of `PlayerDetails` objects. A `PlayerDetail` object contains four variables--`playerId`, `name`, `position`, and `salary`--which are copies of the `PlayerBean` persistent fields. The `RosterClient` calls the `getPlayersOfTeam` method as follows:

>     playerList = myRoster.getPlayersOfTeam("T2");

> #### 2. RosterBean

> The `getPlayersOfTeam` method of the `RosterBean` session bean locates the `LocalTeam` object of the target team by invoking the `findByPrimaryKey` method. Next, the `getPlayersOfTeam` method calls the `getPlayers` method of the `TeamBean` entity bean. Here is the source code for the `getPlayersOfTeam` method:

>     public ArrayList getPlayersOfTeam(String teamId) {

>       Collection players = null;

>       try {
>         LocalTeam team = teamHome.findByPrimaryKey(teamId);
>         players = team.getPlayers();
>       } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }

>       return copyPlayersToDetails(players);
>     }

> The `getPlayersOfTeam` method returns the `ArrayList` of `PlayerDetails` objects that is generated by the `copyPlayersToDetails` method:

>     private ArrayList copyPlayersToDetails(Collection players) {

>       ArrayList detailsList = new ArrayList();
>       Iterator i = players.iterator();

>       while (i.hasNext()) {
>         LocalPlayer player = (LocalPlayer) i.next();
>         PlayerDetails details =
>           new PlayerDetails(player.getPlayerId(),
>             player.getName(), player.getPosition(),
>             player.getSalary());
>           detailsList.add(details);
>       }

>       return detailsList;
>     }

> #### 3. TeamBean

> The `getPlayers` method of the `TeamBean` entity bean is an access method of the `players` relationship field:

>     public abstract Collection getPlayers();

> This method is exposed to local clients because it is defined in the local interface, `LocalTeam`:

>     public Collection getPlayers();

> When invoked by a local client, a `get` access method returns a reference to the relationship field. If the local client alters the object returned by a `get` access method, it also alters the value of the relationship field inside the entity bean. For example, a local client of the `TeamBean` entity bean could drop a player from a team as follows:

>     LocalTeam team = teamHome.findByPrimaryKey(teamId);
>     Collection players = team.getPlayers();
>     players.remove(player);

> If you want to prevent a local client from modifying a relationship field in this manner, you should take the approach described in the next section.

> ### Getting a Copy of a Team's Players

> In contrast to the methods discussed in the preceding section, the methods in this section demonstrate the following techniques:

> - Filtering the information passed back to the remote client
> - Preventing the local client from directly modifying a relationship field

> #### 1. RosterClient

> If you wanted to hide the salary of a player from a remote client, you would require the client to call the `getPlayersOfTeamCopy` method of the `RosterBean` session bean. Like the `getPlayersOfTeam` method, the `getPlayersOfTeamCopy` method returns an `ArrayList` of `PlayerDetails` objects. However, the objects returned by `getPlayersOfTeamCopy` are different: their `salary` variables have been set to zero. The `RosterClient` calls the `getPlayersOfTeamCopy` method as follows:

>     playerList = myRoster.getPlayersOfTeamCopy("T5");

> #### 2. RosterBean

> Unlike the `getPlayersOfTeam` method, the `getPlayersOfTeamCopy` method does not invoke the `getPlayers` access method that is exposed in the `LocalTeam` interface. Instead, the `getPlayersOfTeamCopy` method retrieves a copy of the player information by invoking the `getCopyOfPlayers` business method that is defined in the `LocalTeam` interface. As a result, the `getPlayersOfTeamCopy` method cannot modify the `players` relationship field of `TeamBean`. Here is the source code for the `getPlayersOfTeamCopy` method of `RosterBean`:

>     public ArrayList getPlayersOfTeamCopy(String teamId) {

>       ArrayList playersList = null;

>       try {
>         LocalTeam team = teamHome.findByPrimaryKey(teamId);
>         playersList = team.getCopyOfPlayers();
>       } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }

>       return playersList;
>     }

> #### 3. TeamBean

> The `getCopyOfPlayers` method of `TeamBean` returns an `ArrayList` of `PlayerDetails` objects. To create this `ArrayList`, the method iterates through the `Collection` of related `LocalPlayer` objects and copies information to the variables of the `PlayerDetails` objects. The method copies the values of `PlayerBean` persistent fields--except for the `salary` field, which it sets to zero. As a result, a player's salary is hidden from a client that invokes the `getPlayersOfTeamCopy` method. The source code for the `getCopyOfPlayers` method of `TeamBean` follows.

>     public ArrayList getCopyOfPlayers() {

>       ArrayList playerList = new ArrayList();
>       Collection players = getPlayers();

>       Iterator i = players.iterator();
>       while (i.hasNext()) {
>         LocalPlayer player = (LocalPlayer) i.next();
>         PlayerDetails details =
>           new PlayerDetails(player.getPlayerId(),
>             player.getName(), player.getPosition(), 0.00);
>           playerList.add(details);
>       }

>       return playerList;
>     }

> ### Finding the Players by Position

> #### 1. RosterClient

> The client starts the procedure by invoking the `getPlayersByPosition` method of the `RosterBean` session bean:

>     playerList = myRoster.getPlayersByPosition("defender");

> #### 2. RosterBean

> The `getPlayersByPosition` method retrieves the `players` list by invoking the `findByPosition` method of the `PlayerBean` entity bean:

>     public ArrayList getPlayersByPosition(String position) {

>       Collection players = null;

>       try {
>         players = playerHome.findByPosition(position);
>       } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }

>       return copyPlayersToDetails(players);
>     }

> #### 3. PlayerBean

> The `LocalPlayerHome` interface defines the `findByPosition` method:

>     public Collection findByPosition(String position)
>       throws FinderException;

> Because the `PlayerBean` entity bean uses container-managed persistence, the entity bean class (`PlayerBean`) does not implement its finder methods. To specify the queries associated with the finder methods, EJB QL queries must be defined in the bean's deployment descriptor. For example, the `findByPosition` method has this EJB QL query:

>     SELECT DISTINCT OBJECT(p) FROM Player p
>     WHERE p.position = ?1

> At runtime, when the container invokes the `findByPosition` method, it will execute the corresponding SQL `SELECT` statement.

> For details about EJB QL, please refer to Chapter 29. To learn how to view and edit an EJB QL query in `deploytool`, see the section Finder/Select Methods Dialog Box (PlayerBean).

> ### Getting the Sports of a Player

> #### 1. RosterClient

> The client invokes the `getSportsOfPlayer` method of the `RosterBean` session bean:

>     sportList = myRoster.getSportsOfPlayer("P28");

> #### 2. RosterBean

> The `getSportsOfPlayer` method returns an `ArrayList` of `String` objects that represent the sports of the specified player. It constructs the `ArrayList` from a `Collection` returned by the `getSports` business method of the `PlayerBean entity` bean. Here is the source code for the `getSportsOfPlayer` method of the `RosterBean` session bean:

>     public ArrayList getSportsOfPlayer(String playerId) {

>       ArrayList sportsList = new ArrayList();
>       Collection sports = null;

>       try {
>         LocalPlayer player =
>           playerHome.findByPrimaryKey(playerId);
>         sports = player.getSports();
>       } catch (Exception ex) {
>         throw new EJBException(ex.getMessage());
>       }

>       Iterator i = sports.iterator();
>       while (i.hasNext()) {
>         String sport = (String) i.next();
>         sportsList.add(sport);
>       }
>       return sportsList;
>     }

> #### 3. PlayerBean

> The `getSports` method is a wrapper for the `ejbSelectSports` method. Because the parameter of the `ejbSelectSports` method is of type `LocalPlayer`, the `getSports` method passes along a reference to the entity bean instance. The `PlayerBean` class implements the `getSports` method as follows:

>     public Collection getSports() throws FinderException {

>       LocalPlayer player =
>         (team.LocalPlayer)context.getEJBLocalObject();
>       return ejbSelectSports(player);
>     }

> The `PlayerBean` class defines the `ejbSelectSports` method:

>     public abstract Collection ejbSelectSports(LocalPlayer player)
>       throws FinderException;

> The bean's deployment descriptor specifies the following EJB QL query for the `ejbSelectSports` method:

>     SELECT DISTINCT t.league.sport
>     FROM Player p, IN (p.teams) AS t
>     WHERE p = ?1

> Because `PlayerBean` uses container-managed persistence, when the `ejbSelectSports` method is invoked the EJB container will execute its corresponding SQL `SELECT` statement.

Download PDF Home History |  | API Search Feedback FAQ

All of the material in The J2EE(TM) 1.4 Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.