|
Home TOC Index |
|
Search
Feedback |
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
j2eetutorial/examples/src/ejb/cmprosterdirectory.Creating a Player
1. RosterClient
The
RosterClientinvokes thecreatePlayerbusiness method of theRosterEJBsession bean. In the following line of code, the type of themyRosterobject isRoster, the remote interface ofRosterEJB. The argument of thecreatePlayermethod is aPlayerDetailsobject, which encapsulates information about a particular player.myRoster.createPlayer(new PlayerDetails("P1", "Phil Jones", "goalkeeper", 100.00));2. RosterEJB
The
createPlayermethod of theRosterEJBsession bean creates a new instance of thePlayerEJBentity bean. Because the accessPlayerEJBis local, thecreatemethod is defined in the local home interface,LocalPlayerHome. The type of theplayerHomeobject isLocalPlayerHome. Here is the source code for thecreatePlayermethod: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. PlayerEJB
The
ejbCreatemethod assigns the input arguments to the bean's persistent fields by calling thesetaccess methods. After invoking theejbCreatemethod, the container saves the persistent fields in the database by issuing a SQLINSERTstatement. The code for theejbCreatemethod follows.public String ejbCreate (String id, String name, String position,double salary) throws CreateException { setPlayerId(id); setName(name); setPosition(position); setSalary(salary); return id; }Adding a Player to a Team
1. RosterClient
The
RosterClientcalls theaddPlayerbusiness method of theRosterEJBsession bean. TheP1andT1parameters are the primary keys of thePlayerEJBandTeamEJBinstances, respectively.myRoster.addPlayer("P1", "T1");2. RosterEJB
The
addPlayermethod performs two steps. First, it callsfindByPrimaryKeyto locate thePlayerEJBandTeamEJBinstances. Second, it invokes theaddPlayerbusiness method of theTeamEJBentity bean. Here is the source code for theaddPlayermethod of theRosterEJBsession 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. TeamEJB
The
TeamEJBentity bean has a relationship field namedplayers, aCollectionthat represents the players that belong to the team. The access methods for theplayersrelationship field are as follows:public abstract Collection getPlayers(); public abstract void setPlayers(Collection players);The
addPlayermethod ofTeamEJBinvokes thegetPlayersaccess method to fetch theCollectionof relatedLocalPlayerobjects. Next, theaddPlayermethod invokes theaddmethod of theCollectioninterface. Here is the source code for theaddPlayermethod: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 theremovePlayermethod of theRosterEJBsession bean:myRoster.removePlayer("P4");2. RosterEJB
The
removePlayermethod locates thePlayerEJBinstance by callingfindByPrimaryKeyand then invokes theremovemethod on the instance. This invocation signals the container to delete the row in the database that corresponds to thePlayerEJBinstance. The container also removes the item for this instance from theplayersrelationship field in theTeamEJBentity bean. By this removal, the container automatically updates theTeamEJB-PlayerEJBrelationship. Here is theremovePlayermethod of theRosterEJBsession 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
P2from teamT1, the client would call thedropPlayermethod of theRosterEJBsession bean:myRoster.dropPlayer("P2", "T1");2. RosterEJB
The
dropPlayermethod retrieves thePlayerEJBandTeamEJBinstances by calling theirfindByPrimaryKeymethods. Next, it invokes thedropPlayerbusiness method of theTeamEJBentity bean. ThedropPlayermethod of theRosterEJBsession 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. TeamEJB
The
dropPlayermethod updates theTeamEJB-PlayerEJBrelationship. First, the method retrieves theCollectionofLocalPlayerobjects that correspond to theplayersrelationship field. Next, it drops the targetplayerby calling theremovemethod of theCollectioninterface. Here is thedropPlayermethod of theTeamEJBentity 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
getPlayersOfTeammethod of theRosterEJBsession bean. This method returns anArrayListofPlayerDetailsobjects. APlayersDetailsobject contains four variables--playerId,name,position, andsalary--which are copies of thePlayerEJBpersistent fields. TheRosterClientcalls thegetPlayersOfTeammethod as follows:playerList = myRoster.getPlayersOfTeam("T2");2. RosterEJB
The
getPlayersOfTeammethod of theRosterEJBsession bean locates theLocalTeamobject of the target team by invoking thefindByPrimaryKeymethod. Next, thegetPlayersOfTeammethod calls thegetPlayersmethod of theTeamEJBentity bean. Here is the source code for thegetPlayersOfTeammethod: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
getPlayersOfTeammethod returns theArrayListofPlayerDetailsobjects that is generated by thecopyPlayersToDetailsmethod: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. TeamEJB
The
getPlayersmethod of theTeamEJBentity bean is an access method of theplayersrelationship 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
getaccess method returns a reference to the relationship field. If the local client alters the object returned by agetaccess method, it also alters the value of the relationship field inside the entity bean. For example, a local client of theTeamEJBentity 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
getPlayersOfTeamCopymethod of theRosterEJBsession bean. Like thegetPlayersOfTeammethod, thegetPlayersOfTeamCopymethod returns anArrayListofPlayerDetailsobjects. However, the objects returned bygetPlayersOfTeamCopyare different--theirsalaryvariables have been set to zero. TheRosterClientcalls thegetPlayersOfTeamCopymethod as follows:playerList = myRoster.getPlayersOfTeamCopy("T5");2. RosterEJB
Unlike the
getPlayersOfTeammethod, thegetPlayersOfTeamCopymethod does not invoke thegetPlayersaccess method that is exposed in theLocalTeaminterface. Instead, thegetPlayersOfTeamCopymethod retrieves a copy of the player information by invoking thegetCopyOfPlayersbusiness method that is defined in theLocalTeaminterface. As a result, thegetPlayersOfTeamCopymethod cannot modify theplayersrelationship field ofTeamEJB. Here is the source code for thegetPlayersOfTeamCopymethod ofRosterEJB: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. TeamEJB
The
getCopyOfPlayersmethod ofTeamEJBreturns anArrayListofPlayerDetailsobjects. To create thisArrayList, the method iterates through theCollectionof relatedLocalPlayerobjects and copies information to the variables of thePlayerDetailsobjects. The method copies the values ofPlayerEJBpersistent fields--except for thesalaryfield, which it sets to zero. As a result, a player's salary is hidden from a client that invokes thegetPlayersOfTeamCopymethod. The source code for thegetCopyOfPlayersofTeamEJBfollows.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
getPlayersByPositionmethod of theRosterEJBsession bean:playerList = myRoster.getPlayersByPosition("defender");2. RosterEJB
The
getPlayersByPositionmethod retrieves theplayerslist by invoking thefindByPositionmethod of thePlayerEJBentity 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. PlayerEJB
The
LocalPlayerHomeinterface defines thefindByPositionmethod:public Collection findByPosition(String posistion) throws FinderException;Because the
PlayerEJBentity 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, thefindByPositionmethod has this EJB QL query:SELECT DISTINCT OBJECT(p) FROM Player p WHERE p.position = ?1The
deploytoolutility translates the EJB QL query into a SQLSELECTstatement. At runtime, when the container invokes thefindByPositionmethod, it will execute the SQLSELECTstatement.For details about EJB QL, please refer to Chapter 8. To learn how to view and edit an EJB QL query in
deploytool, see the section Finder/Select Methods Dialog Box (PlayerEJB).Getting the Sports of a Player
1. RosterClient
The client invokes the
getSportsOfPlayermethod of theRosterEJBsession bean:sportList = myRoster.getSportsOfPlayer("P28");2. RosterEJB
The
getSportsOfPlayermethod returns anArrayListofStringobjects that represent the sports of the specified player. It constructs theArrayListfrom aCollectionreturned by thegetSportsbusiness method of thePlayerEJB entitybean. Here is the source code for thegetSportsOfPlayermethod of theRosterEJBsession 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. PlayerEJB
The
getSportsmethod is a wrapper for theejbSelectSportsmethod. Since the parameter of theejbSelectSportsmethod is of typeLocalPlayer, thegetSportsmethod passes along a reference to the entity bean instance. ThePlayerBeanclass implements thegetSportsmethod as follows:public Collection getSports() throws FinderException { LocalPlayer player = (team.LocalPlayer)context.getEJBLocalObject(); return ejbSelectSports(player); }The
PlayerBeanclass defines theejbSelectSportsmethod:public abstract Collection ejbSelectSports(LocalPlayer player) throws FinderException;The bean's deployment descriptor specifies the following EJB QL query for the
ejbSelectSportsmethod:SELECT DISTINCT t.league.sport FROM Player p, IN (p.teams) AS t WHERE p = ?1Before deploying
PlayerEJB, you rundeploytoolto generate SQLSELECTstatements for the bean's EJB QL queries. BecausePlayerEJBuses container-managed persistence, when theejbSelectSportsmethod is invoked the EJB container will execute its corresponding SQLSELECTstatement.
|
Home TOC Index |
|
Search
Feedback |