14.2 14.4.1 MoneyTransfer EJB Home and Remote Interfaces The MoneyTransfer EJB demonstrates the need for distributed transactions and their implementation using bean-managed and containe
Trang 1Please refer to Section 14.3.2 for deployment instructions Recall that MathTool is a
stateless session EJB, so you must specify this in the deployment process Also, be sure to
specify an appropriate JNDI name (e.g., MathTool) for the MathTool EJB
MathToolClient (Fig 14.24) is an application client for the MathTool EJB The user interface consists of a JTextField into which the user can enter an integer, a JButton to invoke MathTool method getFactorial and a JButton to invoke MathTool method getFibonacciSeries The calculation results are displayed in a JTextArea.
The MathToolClient constructor (lines 29–45) invokes method Tool (line 35) to create a new instance of the MathTool EJB Line 38 invokes method createGUI to create and lay out GUI components for the application’s user interface Method createMathTool (lines 48–83) uses an InitialContext (line 53) to look
createMath-up the MathToolHome interface in the JNDI Directory (lines 56–57) Line 65 invokes MathToolHome method create to create a MathTool EJB instance.
Method getFactorialButton (lines 86–122) creates a JButton that, when pressed, invokes MathTool EJB method getFactorial Lines 100–104 parse the number entered in numberTextField and invoke method getFactorial of the MathTool remote interface Lines 107–108 display the factorial in resultsText- Area Lines 113–115 catch a RemoteException if there is an error invoking method getFactorial.
Method getFibonacciButton (lines 125–182) creates a JButton that, when clicked, invokes MathTool EJB method getFibonacciSeries Lines 140–145 parse the number entered in numberTextField and invoke method getFibonac- ciSeries of the MathTool remote interface Method getFibonacciSeries
returns an array of integers containing a Fibonacci series of the length specified by the
integer argument howMany Lines 148–168 build a StringBuffer containing the Fibonacci series and display the series in resultsTextArea.
14 // create new MathTool EJB
Fig 14.23 MathToolHome interface for creating MathTool EJBs.
Trang 21 // MathToolClient.java
2 // MathToolClient is a GUI for calculating factorials and
3 // Fibonacci series using the MathTool EJB.
4 package com.deitel.advjhtp1.ejb.session.stateless.client; 5
6 // Java core libraries
22 private MathToolHome mathToolHome;
23 private MathTool mathTool;
25 private JTextArea resultsTextArea;
26 private JTextField numberTextField;
33 // create MathTool for calculating factorials
34 // and Fibonacci series
47 // create MathTool EJB instance
50 // lookup MathToolHome and create MathTool EJB
53 InitialContext initialContext = new InitialContext();
Fig 14.24 MathToolClient for interacting with MathTool EJB (part 1 of 6).
Trang 369 // handle exception if MathTool EJB is not found
70 catch ( NamingException namingException ) {
74 // handle exception when creating MathTool EJB
75 catch ( RemoteException remoteException ) {
79 // handle exception when creating MathTool EJB
80 catch ( CreateException createException ) {
83 } // end method createMathTool
85 // create JButton for calculating factorial
86 private JButton getFactorialButton()
103 // get Factorial of number input by user
104 int result = mathTool.getFactorial( number ); 105
Fig 14.24 MathToolClient for interacting with MathTool EJB (part 2 of 6).
Trang 4106 // display results in resultsTextArea
112 // handle exception calculating factorial
113 catch ( RemoteException remoteException ) {
124 // create JButton for generating Fibonacci series
125 private JButton getFibonacciButton()
139 // get number entered by user
140 int number = Integer.parseInt(
141 numberTextField.getText() );
142
143 // get Fibonacci series
144 int[] series = mathTool.getFibonacciSeries(
155 // append each number in series to buffer
156 for ( int i = 0 ; i < series.length; i++ ) { 157
Fig 14.24 MathToolClient for interacting with MathTool EJB (part 3 of 6).
Trang 5158 // do not add comma before first number
170 } // end try
171
172 // handle exception calculating series
173 catch ( RemoteException remoteException ) {
184 // create lay out GUI components
185 public void createGUI()
186 {
187 // create JTextArea to show results
188 resultsTextArea = new JTextArea();
189 resultsTextArea.setLineWrap( true );
190 resultsTextArea.setWrapStyleWord( true );
191 resultsTextArea.setEditable( false );
192
193 // create JTextField for user input
194 numberTextField = new JTextField( 10 );
195
196 // create JButton for calculating factorial
197 JButton factorialButton = getFactorialButton();
198
199 // create JButton for generating Fibonacci series
200 JButton fibonacciButton = getFibonacciButton();
Trang 6211 // add input components to new JPanel
212 JPanel inputPanel = new JPanel( new FlowLayout() );
213 inputPanel.add( new JLabel( "Enter an integer: " ) );
214 inputPanel.add( numberTextField );
215
216 // add JButton components to new JPanel
217 JPanel buttonPanel = new JPanel( new FlowLayout() );
232 // get WindowListener for exiting application
233 private WindowListener getWindowListener()
244 // handle exception when removing MathTool EJB
245 catch ( RemoveException removeException ) {
246 removeException.printStackTrace();
247 System.exit( -1 );
248 }
249
250 // handle exception when removing MathTool EJB
251 catch ( RemoteException remoteException ) {
Trang 714.4 EJB Transactions
The Java 2 Enterprise Edition supports distributed transactions A distributed transaction
is a transaction that includes multiple databases or multiple application servers For ple, a distributed transaction could transfer funds from an account at one bank into an ac-count at another bank atomically
exam-J2EE supports two methods for defining transaction boundaries: bean-managed action demarcation and container-managed transaction demarcation Bean-managed
trans-transaction demarcation requires the EJB developer to code the trans-transaction boundaries
manually in the EJBs using the Java Transaction API (JTA) Container-managed
transac-tion demarcatransac-tion allows the EJB deployer to specify transactransac-tion boundaries declarativelywhen deploying EJBs
Software Engineering Observation 14.2
Entity EJBs may use only container-managed transaction demarcation. 14.2
14.4.1 MoneyTransfer EJB Home and Remote Interfaces
The MoneyTransfer EJB demonstrates the need for distributed transactions and their
implementation using bean-managed and container-managed transaction demarcation In
this example, we transfer money from an account at BankABC to an account at BankXYZ.
We first withdraw money from an account at BankABC and then deposit the same amount
at BankXYZ Transactions are needed to ensure that the money is “put back” in the
Bank-264 MathToolClient client = new MathToolClient();
265 }
266 }
Fig 14.24 MathToolClient for interacting with MathTool EJB (part 6 of 6).
Trang 8ABC account if the deposit at BankXYZ fails We also need to ensure that if the withdrawal from BankABC fails, the money is not deposited at BankXYZ.
The MoneyTransfer remote interface (Fig 14.25) provides methods for
transfer-ring money between accounts and for getting the balances of accounts at two different
banks Method transfer (line 15) transfers the given amount of money from an account
at BankABC to an account at BankXYZ Method getBankABCBalance (line 18) returns the account balance at BankABC Method getBankXYZBalance (line 21) returns the account balance at BankXYZ Interface MoneyTransferHome (Fig 14.26) provides method create (lines 15–16) for creating MoneyTransfer EJB instances.
14 // transfer amount from BankABC to BankXYZ
15 public void transfer( double amount ) throws RemoteException;
17 // get BankABC account balance
18 public double getBankABCBalance() throws RemoteException;
20 // get BankXYZ account balance
21 public double getBankXYZBalance() throws RemoteException;
Trang 914.4.2 Bean-Managed Transaction Demarcation
Bean-managed transaction demarcation requires the EJB developer to code the transaction
boundaries manually in the EJBs Bean-managed transaction demarcation may be usedonly with session EJBs
MoneyTransferEJB (Fig 14.27) implements the MoneyTransfer remote
inter-face using bean-managed transaction demarcation to ensure atomicity of the database
updates in method transfer (lines 26–81) Lines 29–30 create a UserTransaction Line 34 begins the transaction by invoking UserTransaction method begin All statements after the transaction begins are part of the transaction until the transaction is committed or rolled back
14 // create MoneyTransfer EJB
15 public MoneyTransfer create() throws RemoteException,
1 // MoneyTransferEJB.java
2 // MoneyTransferEJB is a stateless session EJB for transferring
3 // funds from an Account at BankABC to an Account at BankXYZ
4 // using bean-managed transaction demarcation.
24
25 // transfer funds from BankABC to BankXYZ
26 public void transfer( double amount ) throws EJBException
28 // create transaction for transferring funds
29 UserTransaction transaction =
Fig 14.27 MoneyTransferEJB implementation of MoneyTransfer remote
interface using bean-managed transaction demarcation (part 1 of 6).Fig 14.26 MoneyTransferHome interface for creating MoneyTransfer
EJBs (part 2 of 2)
Trang 1037 // catch exception if method begin fails
40 // throw EJBException indicating transaction failed
44 // transfer funds from account in BankABC to account
45 // in BankXYZ using bean-managed transaction demarcation
72 // handle exception when rolling back transaction
73 catch ( SystemException systemException ) {
74 throw new EJBException( systemException );
77 // throw EJBException indicating transaction failed
82
Fig 14.27 MoneyTransferEJB implementation of MoneyTransfer remote
interface using bean-managed transaction demarcation (part 2 of 6)
Trang 1183 // get balance of Account at BankABC
84 public double getBankABCBalance() throws EJBException
86 // get balance of Account at BankABC
89 // select balance for Account # 12345
90 String select = "SELECT balance FROM Account " +
106 // handle exception when getting Account balance
107 catch ( SQLException sqlException ) {
108 throw new EJBException( sqlException );
110
111 } // end method getBankABCBalance
112
113 // get balance of Account at BankXYZ
114 public double getBankXYZBalance() throws EJBException
115 {
116 // get balance of Account at BankXYZ
117 try {
118
119 // select balance for Account # 54321
120 String select = "SELECT balance FROM Account " +
Fig 14.27 MoneyTransferEJB implementation of MoneyTransfer remote
interface using bean-managed transaction demarcation (part 3 of 6)
Trang 12135
136 // handle exception when getting Account balance
137 catch ( SQLException sqlException ) {
138 throw new EJBException( sqlException );
152 // create MoneyTransfer instance
154
155 // remove MoneyTransfer instance
156 public void ejbRemove() throws EJBException
157 {
158 closeDatabaseResources();
159 }
160
161 // passivate MoneyTransfer instance
162 public void ejbPassivate() throws EJBException
163 {
164 closeDatabaseResources();
165 }
166
167 // activate MoneyTransfer instance
168 public void ejbActivate() throws EJBException
169 {
170 openDatabaseResources();
171 }
172
173 // close database Connections and PreparedStatements
174 private void closeDatabaseResources() throws EJBException
Fig 14.27 MoneyTransferEJB implementation of MoneyTransfer remote
interface using bean-managed transaction demarcation (part 4 of 6)
Trang 13186 // close database Connections
194 // handle exception closing database connections
195 catch ( SQLException sqlException ) {
196 throw new EJBException( sqlException );
198
199 } // end method closeDatabaseResources
200
201 // open database Connections and create PreparedStatements
202 private void openDatabaseResources() throws EJBException
204 // look up the BankABC and BankXYZ DataSources and create
205 // Connections for each
206 try {
207 Context initialContext = new InitialContext();
208
209 // get DataSource reference from JNDI directory
210 DataSource dataSource = ( DataSource )
224 String withdrawal = "UPDATE Account SET balance = " +
225 "balance - ? WHERE accountID = 12345" ;
232 String deposit = "UPDATE Account SET balance = " +
233 "balance + ? WHERE accountID = 54321" ;
234
235 depositStatement =
236 bankTwoConnection.prepareStatement( deposit );
237
Fig 14.27 MoneyTransferEJB implementation of MoneyTransfer remote
interface using bean-managed transaction demarcation (part 5 of 6)
Trang 14Lines 48–51 withdraw the given transfer amount from an account in the BankABC database Lines 53–56 deposit the given transfer amount in an account in the BankXYZ database Both of these updates are part of the transaction begun on line 34 even though they are in separate databases Line 59 commits the transaction to save the
updates to each database
Lines 65–79 catch any Exceptions thrown from lines 46–61 Line 69 invokes UserTransaction method rollback to undo any updates that were made within the transaction boundaries This rollback ensures that if any critical part of method transfer failed, all of the changes made in both databases are undone to ensure the
integrity of the data Lines 73–75 catch a SystemException, which is thrown by UserTransaction method rollback if the rollback fails Lines 74 and 78 throw EJBExceptions to aid in debugging the application
Methods getBankABCBalance (lines 84–111) and getBankXYZBalance (lines 114–141) execute simple SQL SELECT statements to retrieve the balances of the accounts at each bank Methods setSessionContext (lines 144–150) and ejbActi- vate (lines 168–171) invoke method openDatabaseResources (lines 202–250) to create Connections and PreparedStatements for each database for use throughout the lifetime of the MoneyTransfer EJB instance Methods ejbRemove (lines 156– 159) and ejbPassivate (lines 162–165) invoke method closeDatabaseRe- sources (lines 174–199) to close the Connections and PreparedStatements.
14.4.3 Container-Managed Transaction Demarcation
Container-managed transaction demarcation allows the EJB developer to implement an
EJB without specifying transaction boundaries The EJB deployer provides transaction marcation semantics declaratively when deploying the application
de-MoneyTransferEJB (Fig 14.28) implements the MoneyTransfer remote face using container-managed transaction demarcation Method transfer (lines 25–51)
inter-is similar to method transfer in Fig 14.27 Note, however, that thinter-is version of method transfer does not declare any transaction boundaries, as this is now the responsibility
238 } // end try
239
240 // handle exception if DataSource not found in directory
241 catch ( NamingException namingException ) {
242 throw new EJBException( namingException );
244
245 // handle exception getting Connection to DataSource
246 catch ( SQLException sqlException ) {
247 throw new EJBException( sqlException );
248 }
249
250 } // end method openDatabaseResources
251 }
Fig 14.27 MoneyTransferEJB implementation of MoneyTransfer remote
interface using bean-managed transaction demarcation (part 6 of 6)
Trang 15of the EJB deployer The EJB deployer specifies the transaction semantics using one of thesix transaction types listed in Fig 14.29
1 // MoneyTransferEJB.java
2 // MoneyTransferEJB is a stateless session EJB for transferring
3 // funds from an Account at BankABC to an Account at BankXYZ
4 // using container-managed transaction demarcation.
5 package com.deitel.advjhtp1.ejb.transactions.containermanaged; 6
7 // Java core libraries
23
24 // transfer funds from BankABC to BankXYZ
25 public void transfer( double amount ) throws EJBException
27 // transfer funds from account in BankABC to account in
28 // BankXYZ using container-managed transaction demarcation
43 // handle exception withdrawing and depositing
Fig 14.28 MoneyTransferEJB implementation of MoneyTransfer remote
interface using container-managed transaction demarcation (part 1 of 5)
Trang 1646 // throw EJBException to indicate transfer failed
47 // and roll back container-managed transaction
48 throw new EJBException( sqlException );
52
53 // get balance of Account at BankABC
54 public double getBankABCBalance() throws EJBException
56 // get balance of Account at BankABC
59 // select balance for Account # 12345
60 String select = "SELECT balance FROM Account " +
76 // handle exception when getting Account balance
78 throw new EJBException( sqlException );
81 } // end method getBankABCBalance
82
83 // get balance of Account at BankXYZ
84 public double getBankXYZBalance() throws EJBException
86 // get balance of Account at BankXYZ
89 // select balance for Account # 54321
90 String select = "SELECT balance FROM Account " +
Fig 14.28 MoneyTransferEJB implementation of MoneyTransfer remote
interface using container-managed transaction demarcation (part 2 of 5)
Trang 1798 // get first record in ResultSet and return balance
106 // handle exception when getting Account balance
107 catch ( SQLException sqlException ) {
108 throw new EJBException( sqlException );
122 // create MoneyTransfer instance
124
125 // remove MoneyTransfer instance
126 public void ejbRemove() throws EJBException
127 {
128 closeDatabaseResources();
129 }
130
131 // passivate MoneyTransfer instance
132 public void ejbPassivate() throws EJBException
133 {
134 closeDatabaseResources();
135 }
136
137 // activate MoneyTransfer instance
138 public void ejbActivate() throws EJBException
139 {
140 openDatabaseResources();
141 }
142
143 // close database Connections and PreparedStatements
144 private void closeDatabaseResources() throws EJBException
145 {
146 // close database resources
147 try {
148
Fig 14.28 MoneyTransferEJB implementation of MoneyTransfer remote
interface using container-managed transaction demarcation (part 3 of 5)
Trang 18164 // handle exception closing database connections
165 catch ( SQLException sqlException ) {
166 throw new EJBException( sqlException );
168
169 } // end method closeDatabaseConnections
170
171 // open database Connections and create PreparedStatements
172 private void openDatabaseResources() throws EJBException
174 // look up the BankABC and BankXYZ DataSources and create
175 // Connections for each
176 try {
177 Context initialContext = new InitialContext();
178
179 // get DataSource reference from JNDI directory
180 DataSource dataSource = ( DataSource )
194 String withdrawal = "UPDATE Account SET balance = " +
195 "balance - ? WHERE accountID = 12345" ;
196
197 withdrawalStatement =
198 bankOneConnection.prepareStatement( withdrawal );
199
Fig 14.28 MoneyTransferEJB implementation of MoneyTransfer remote
interface using container-managed transaction demarcation (part 4 of 5)
Trang 19Line 66 throws an EJBException in response to any SQLException thrown from lines 29–41 The EJBContainer rolls back the current transaction when method transfer throws an EJBException (line 48).
Figure 14.29 lists the available transaction types for container-managed persistence.The deployer specifies the transaction type for each business method when deploying theapplication
200 // prepare deposit statment for account #54321 at
201 // BankXYZ
202 String deposit = "UPDATE Account SET balance = " +
203 "balance + ? WHERE accountID = 54321" ;
210 // handle exception if DataSource not found in directory
211 catch ( NamingException namingException ) {
212 throw new EJBException( namingException );
214
215 // handle exception getting Connection to DataSource
216 catch ( SQLException sqlException ) {
217 throw new EJBException( sqlException );
218 }
219
220 } // end method openDatabaseConnections
221 }
Transaction Type Description
NotSupported Method does not support transactions The EJB container suspends the
exist-ing transaction context if the method is invoked within a transaction context
Required Method requires a transaction The EJB container creates a new transaction if
the method is invoked without an existing transaction context and commits the transaction at the end of the method
Supports Method supports transactions The EJB container will not create a new
transac-tion if the method is invoked without an existing transactransac-tion context, but will execute the method as part of an existing transaction context if one is available
RequiresNew Method requires a new transaction The EJB container suspends the existing
transaction context and starts a new transaction if the method is invoked as part of another transaction
Fig 14.29
Fig 14.29 Transaction types for container-managed transaction demarcation
(part 1 of 2)
Fig 14.28 MoneyTransferEJB implementation of MoneyTransfer remote
interface using container-managed transaction demarcation (part 5 of 5)
Trang 2014.4.4 MoneyTransfer EJB Client
MoneyTransferEJBClient (Fig 14.30) provides a user interface for interacting with
the MoneyTransfer EJB Lines 24–26 declare JTextFields to display the account balances and accept a user-input transfer amount Line 34 invokes method create- MoneyTransfer to create a new MoneyTransfer EJB instance Line 37 invokes method createGUI to create and lay out GUI components for the application The GUI consists of JTextFields for displaying account balances and inputting the transfer amount and a JButton for transferring funds Line 40 invokes method displayBal- ances to display the current account balances at BankABC and BankXYZ.
Method createMoneyTransfer (lines 47–80) uses the MoneyTransferHome interface to create a MoneyTransfer EJB instance Line 51 creates an InitialCon- text for locating the MoneyTransfer EJB in the JNDI directory Lines 54–59 invoke InitialContext method lookup to get a remote reference to the MoneyTrans- ferHome interface Line 62 creates a new MoneyTransfer EJB instance by invoking MoneyTransferHome method create.
Method getTransferButton (lines 108–142) creates a JButton to transfer funds from BankABC to BankXYZ Lines 120–124 read the transfer amount from the user and invoke MoneyTransfer method transfer Line 127 invokes method displayBalances to update the display with the new account balances
Mandatory The method must execute in an existing transaction context The EJB
con-tainer throws a TransactionRequiredException if the method is
invoked without a valid transaction context
Never The method must not execute in a transaction context The EJB container
throws a RemoteException if the method is invoked inside a transaction
context
1 // MoneyTransferEJBClient.java
2 // MoneyTransferEJBClient is a client for interacting with
3 // the MoneyTransfer EJB.
Fig 14.30 MoneyTransferEJBClient for interacting with
MoneyTransfer EJB (part 1 of 6).
Transaction Type Description
Fig 14.29
Fig 14.29 Transaction types for container-managed transaction demarcation
(part 2 of 2)
Trang 2124 private JTextField bankABCBalanceTextField;
25 private JTextField bankXYZBalanceTextField;
26 private JTextField transferAmountTextField;
46 // create MoneyTransferEJB for transferring money
47 private void createMoneyTransfer( String JNDIName )
53 // lookup MoneyTransfer EJB
54 Object homeObject = context.lookup( JNDIName );
Fig 14.30 MoneyTransferEJBClient for interacting with
MoneyTransfer EJB (part 2 of 6).
Trang 2265
66 // handle exception when looking up MoneyTransfer EJB
67 catch ( NamingException namingException ) {
70
71 // handle exception when looking up MoneyTransfer EJB
72 catch ( CreateException createException ) {
76 // handle exception when looking up MoneyTransfer EJB
77 catch ( RemoteException remoteException ) {
80 } // end method createMoneyTransfer
82 // display balance in account at BankABC
83 private void displayBalances()
87 // get and display BankABC Account balance
88 double balance = moneyTransfer.getBankABCBalance();
100 // handle exception when invoke MoneyTransfer EJB methods
101 catch ( RemoteException remoteException ) {
107 // create button to transfer funds between accounts
108 private JButton getTransferButton()
Fig 14.30 MoneyTransferEJBClient for interacting with
MoneyTransfer EJB (part 3 of 6).
Trang 23117 try {
118
119 // get transfer amount from JTextField
120 double amount = Double.parseDouble(
121 transferAmountTextField.getText() ); 122
130 // handle exception when transferring money
131 catch ( RemoteException remoteException ) {
144 // create and lay out GUI components
145 private void createGUI()
146 {
147 // create JTextFields for user input and display
148 bankABCBalanceTextField = new JTextField( 10 );
156 // create button to transfer between accounts
157 JButton transferButton = getTransferButton();
158
159 // layout user interface
160 Container contentPane = getContentPane();
161 contentPane.setLayout( new GridLayout( 3 2 ) );
Fig 14.30 MoneyTransferEJBClient for interacting with
MoneyTransfer EJB (part 4 of 6).
Trang 24174 // get WindowListener for exiting application
175 private WindowListener getWindowListener()
176 {
177 // remove MoneyTransfer EJB when user exits application
178 return new WindowAdapter() {
187 // handle exception removing MoneyTransfer EJB
188 catch ( RemoveException removeException ) {
189 removeException.printStackTrace();
190 System.exit( 1 );
191 }
192
193 // handle exception removing MoneyTransfer EJB
194 catch ( RemoteException remoteException ) {
Fig 14.30 MoneyTransferEJBClient for interacting with
MoneyTransfer EJB (part 5 of 6).
Trang 25Figure 14.30 shows three screen captures of MoneyTransferEJBClient Enter any legal value in the text field and press the Transfer button This causes the EJB to
update the database entries The client then updates its GUI to reflect the new account ances
bal-Fig 14.30 MoneyTransferEJBClient for interacting with
MoneyTransfer EJB (part 6 of 6).
Trang 2614.4.5 Deploying the MoneyTransfer EJB
The MoneyTransfer EJB accesses two databases that store account information The
examples use the Cloudscape DBMS introduced in Chapter 8, JDBC Follow the directions
in Section 8.5 to set up the databases for the MoneyTransfer EJB The SQL script for the databases, transactions.sql, is on the CD-ROM that accompanies this book If
you have not already done so, please see Appendix E for instructions on integrating scape with the J2EE 1.2.1 reference implementation Add the following
Cloud-|jdbc/BankABC|jdbc:cloudscape:rmi:BankABC;create=true;|jdbc/ BankXYZ|jdbc:cloudscape:rmi:BankXYZ;create=true;
to the jdbc.datasources property in the file fault.properties
C:\j2sdkee1.2.1\config\de-Deploying each versions of the MoneyTransfer EJB is very similar to deploying the other session EJBs When deploying the MoneyTransfer EJB, we must create
resource references to the two databases in the New Enterprise Bean Wizard (Fig 14.31)
Click the Add button to add a new resource reference Fill in the Coded Name and JNDI Name fields with jdbc/BankABC for the BankABC database (Fig 14.32) and jdbc/ BankXYZ for the BankXYZ database (Fig 14.33) In the Transaction Management dialog of the New Enterprise Bean Wizard select Bean-Managed Transactions for the bean-managed version of MoneyTransferEJB (Fig 14.34) or Container-Man- aged Transactions for the container-managed version of MoneyTransferEJB
(Fig 14.35) For the container-managed EJB, select a transaction type for each method (seeSection 14.4.3 for information about transaction types) The rest of the deployment is thesame as the deployment of the other session EJBs Be sure to run the Cloudscape server
before executing MoneyTransferEJBClient.
Fig 14.31
Fig 14.31 Resource References dialog of New Enterprise Bean Wizard.
Trang 2814.5 Internet and World Wide Web Resources
TheServerSide.com is an online community for J2EE developers There are forums, articles and
other resources for building applications with J2EE
SUMMARY
• Every EJB consists of a remote interface, a home interface and an EJB implementation
• The remote interface declares business methods that clients of the EJB may invoke The home
in-terface provides create methods for creating new instances of the EJB, finder methods for
find-ing instances of the EJB and remove methods for removfind-ing instances of the EJB The EJB implementation defines the business methods declared in the remote interface and the create, remove and finder methods of the home interface
Trang 29• EJBs have a complex life cycle that is managed by an EJB container The EJB container createsclasses that implement the home and remote interfaces.
• The J2EE specification defines six roles for implementing enterprise systems Each role is sible for producing some part of an enterprise application
respon-• The remote interface for an EJB declares the business methods that clients of the EJB may invoke
The remote interface must extend interface javax.ejb.EJBObject.
• Each method of the remote interface is required to declare that it throws Exception Each method also may throw application-specific exceptions—for example, an IllegalArgumentException if a provided argument does not meet certain criteria.
java.rmi.Remote-• The home interface for an EJB declares methods for creating, removing and finding EJB instances
The home interface must extend interface javax.ejb.EJBHome.
• Depending on the EJB type (i.e., session or entity), the container invokes EJB implementation
meth-ods that correspond to methmeth-ods create and remove and finder methmeth-ods of the home interface
• The EJB implementation defines the business methods declared in the EJB remote interface and
the create, remove and finder methods declared in the EJB home interface The EJB
imple-mentation must also implement the methods of interface javax.ejb.SessionBean for sion EJBs, or interface javax.ejb.EntityBean for entity EJBs
ses-• The EJB container manages the life cycle, client interactions and method invocations, transactions,security and exceptions of an EJB Clients of an EJB do not interact directly with the EJB When
a client invokes a business method of the EJB’s remote interface, the invocation goes first to theEJB container, which then delegates the business method invocation to the EJB implementation
• Session EJBs exist for the duration of a client’s session Each session EJB instance is associatedwith a single client Session EJBs can manipulate data in a database, but unlike entity EJBs, ses-sion EJBs are not persistent and do not represent database data directly
• Stateful session EJBs maintain state information between business method invocations For ple, a stateful session EJB could maintain information about a customer’s shopping cart while thecustomer browses an on-line store
exam-• Interface SessionContext extends interface EJBContext, which provides methods for
ob-taining information about the EJB container
• The EJB container invokes method ejbCreate when a client invokes a create method in the home interface The EJB implementation must provide an ejbCreate method for each create method declared in the home interface The ejbCreate methods must have the same number and types of arguments as their corresponding create methods
• The EJB container invokes method ejbRemove in response to an invocation of method remove
in the home interface
• The EJB container invokes method ejbPassivate when it determines that the EJB is no longer
needed in memory
• The EJB container invokes method ejbActivate to restore an EJB instance that the container
passivated previously The EJB container activates an EJB instance if a client invokes a businessmethod of that EJB instance
• RMI-IIOP allows RMI objects to interact with CORBA components, which communicate using
the Internet Inter-Orb Protocol (IIOP) CORBA is a language-independent framework for
build-ing distributed systems To enable interoperability among EJBs and CORBA components, EJBscommunicate using RMI-IIOP We discuss CORBA and RMI-IIOP in detail in Chapter 22
• Stateless session EJBs maintain no state information between business method invocations As aresult, any stateless session EJB instance can be used to respond to any client’s request This im-proves the performance of stateless session EJBs over stateful session EJBs
Trang 30• The Java 2 Enterprise Edition supports distributed transactions A distributed transaction is a action that is applied across multiple databases or across multiple EJB servers
trans-• J2EE supports two methods for defining transaction boundaries: bean-managed transaction marcation and container-managed transaction demarcation Bean-managed transaction demarca-tion requires the EJB developer to code the transaction boundaries manually in the EJBs, using theJava Transaction Services Container-managed transaction demarcation allows the EJB deployer
de-to specify transaction boundaries declaratively when deploying EJBs
• Bean-managed transaction demarcation requires the EJB developer to code the transaction aries manually in the EJBs Bean-managed transaction demarcation may be used only with sessionEJBs
bound-• Container-managed transaction demarcation allows the EJB developer to implement an EJB out specifying transaction boundaries The EJB deployer provides transaction demarcation seman-tics declaratively when deploying the application
with-TERMINOLOGY
SELF-REVIEW EXERCISES
14.1 What are the two main types of session EJBs? What is the primary difference between them?
14.2 What three Java objects must the EJB developer provide for each EJB?
14.3 What are the responsibilities of the EJB container?
14.4 How does a client get a remote reference to an EJB instance?
14.5 What types of transaction demarcation can EJBs use? What are the benefits of each type?
ANSWERS TO SELF-REVIEW EXERCISES
14.1 There are stateful session EJBs and stateless session EJBs Stateful session EJBs maintainstate information between business method invocations in a client’s session Stateless session EJBsmaintain no state information between business method invocations
application server Internet Inter-Orb Protocol (IIOP)
bean-managed transaction demarcation J2EE (Java 2 Enterprise Edition)
business methods Java Transaction Services (JTS)
container-managed transaction demarcation java.rmi.RemoteException
CORBA (Common Object Request
Broker Architecture)
java:comp/env naming context javax.ejb.EJBHome
distributed transaction javax.ejb.SessionBean
EJB container JNDI (Java Naming and Directory
Interface) directoryEJB implementation
EJB server least recently used
Enterprise JavaBeans (EJBs) SessionContext interface
entity EJB stateful session EJB
home interface stateless session EJB
IllegalArgumentException
Trang 3114.2 The EJB developer must provide a remote interface, a home interface and the EJB tation
implemen-14.3 The EJB container is responsible for managing the life cycle of the EJB The EJB containercreates classes to implement the home and remote interfaces, and delegates business method invoca-tions to the developer-supplied EJB implementation The EJB container also provides runtime re-sources, such as database connections and transactions, as well as life-cycle management
14.4 A client looks up the EJB’s home interface in a JNDI directory For session EJBs, the client
then invokes one of the home interface’s create methods For entity EJBs, the client can invoke
one of the home interface’s create methods or finder methods.
14.5 EJBs can use either bean-managed or container-managed transaction demarcation managed transaction demarcation allows the developer to have fine-grained control over transactionboundaries Container-managed transaction demarcation simplifies the EJB implementation by al-lowing the EJB deployer to specify transaction boundaries declaratively at deployment time
Bean-EXERCISES
14.1 Stateless session EJBs offer a performance advantage over stateful session beans Convertthe example of Fig 14.3, Fig 14.4, Fig 14.5 and Fig 14.6 from a stateful session EJB to a statelesssession EJB
14.2 Add a new recursive business method power( base, exponent ) to the MathTool
EJB (Fig 14.21, Fig 14.22, Fig 14.23) that, when invoked, returns
base exponent
For example, power( 3, 4 ) = 3 * 3 * 3 * 3 If the exponent is not an integer greater than or
equal to 1, throw an IllegalArgumentException [Hint: The recursion step would use the
relationship
base exponent = base · base exponent – 1
and the terminating condition occurs when exponent is equal to 1 because
base 1 = base
Modify the client in Fig 14.24 to enable the user to enter the base and exponent.]
Trang 3215 Entity EJBs
Objectives
• To understand how entity EJBs represent persistent
data.
• To understand synchronization issues between EJBs
and database data.
• To understand the life-cycle of an entity EJB.
• To understand the advantages and disadvantages of
container-managed and bean-managed persistence.
There is nothing more requisite in business than dispatch.
Joseph Addison
All meanings, we know, depend on the key of interpretation.
George Eliot
Event that are predestined require but little management
They manage themselves They slip into place while we sleep,
and suddenly we are aware that the thing we fear to attempt,
is already accomplished.
Amelia Barr
Trang 3315.1 Introduction
A fundamental part of an enterprise application is the information tier, which maintains
data for the application In this chapter, we introduce entity EJBs, which enable developers
to build object-based representations of information-tier data, such as data stored in a tional database EJB containers provide advanced features that simplify developing entityEJBs For example, based on information provided at deployment time (e.g., SQL queries),
rela-an entity EJB’s container crela-an generate code automatically for storing rela-and retrieving datarepresented by the EJB For entity EJBs that represent more complex data (e.g., data stored
in multiple database tables), the programmer can implement code for storing and retrievingthe data manually
In this chapter, we present two versions of an entity EJB that represents a companyemployee The first version demonstrates an entity EJB that uses JDBC to persist data to arelational database The second version takes advantage of the container’s ability tomanage data storage and retrieval to simplify the EJB implementation After completingthis chapter, you will be able to build and deploy entity EJBs through which business-logiccomponents, such as session EJBs (Chapter 14), can access data in the information tier
15.2 Entity EJB Overview
Each entity EJB instance represents a particular unit of data, such as a record in a database
table There are two types of entity EJBs—those that use bean-managed persistence and those that use container-managed persistence Entity EJBs that use bean-managed persis-
tence must implement code for storing and retrieving data from the persistent data sourcesthey represent For example, an entity EJB that uses bean-managed persistence might usethe JDBC API to store and retrieve data in a relational database Entity EJBs that use con-tainer-managed persistence rely on the EJB container to implement the data-access calls totheir persistent data sources The deployer must supply information about the persistentdata source when deploying the EJB
Outline
15.1 Introduction
15.2 Entity EJB Overview
15.3 Employee Entity EJB
15.4 Employee EJB Home and Remote Interfaces
15.5 Employee EJB with Bean-Managed Persistence
15.5.1 Employee EJB Implementation
15.5.2 Employee EJB Deployment
15.6 Employee EJB with Container-Managed Persistence
15.7 Employee EJB Client
15.8 Internet and World Wide Web Resources
Summary • Terminology • Self-Review Exercises • Answers to Self-Review Exercises • Exercises
Trang 34Entity EJBs provide create methods for creating new EJB instances, remove
methods for removing EJB instances and finder methods for finding EJB instances For
entity EJBs that represent information in a database, each create method performs INSERT operations to create new records in the database, and each remove method per-
forms DELETE operations to remove records from the database Each finder method
locates entity EJB instances that conform to certain search criteria (e.g using SELECT
oper-ations) We discuss each of these method types throughout the chapter
15.3 Employee Entity EJB
In the following sections, we build an entity EJB that represents an Employee We vide two implementations of the Employee EJB The first implementation (Section 15.5) uses bean-managed persistence to store and retrieve Employee information in an under-
pro-lying database The second implementation (Section 15.6) uses container-managed
persis-tence Both of these implementations use the same Employee remote interface and EmployeeHome interface, which we present in Section 15.4.
We use the Cloudscape database for storing Employee data To create the Employee database, run the SQL script employee.sql that is on the CD-ROM that
accompanies the book Please see Chapter 8, JDBC, for instructions on running SQL scripts
in Cloudscape To configure the J2EE reference implementation to use the Employee
database, append the text
|jdbc/Employee|jdbc:cloudscape:rmi:Employee;create=true
to the end of the jdbc.datasources property in the J2EE default.properties
configuration file
15.4 Employee EJB Home and Remote Interfaces
The Employee remote interface (Fig 15.1) provides methods for setting and getting ployee information Note that interface Employee extends interface EJBObject (line 11) This is a requirement for all EJB remote interfaces The Employee remote interface
Em-provides set and get methods for each Employee property, including the
socialSecu-rityNumber, firstName, lastName, title and salary There is no set method for property employeeID because employeeID is the primary key Each set and get method
throws a RemoteException This is required of all methods in the remote interface.
11 public interface Employee extends EJBObject {
Fig 15.1 Employee remote interface for setting and getting Employee
information (part 1 of 2)
Trang 35An EJB instance represents a particular row in the corresponding database table Thehome interface for an entity EJB represents the table as a whole The home interface pro-
vides finder methods for locating particular rows in the table and create methods for
inserting new records Interface EmployeeHome (Fig 15.2) provides finder method
findByPrimaryKey (lines 15–16) to locate instances of the Employee EJB based on
a primary key The primary key for the Employee EJB is the employeeID Method findByPrimaryKey throws a FinderException if the Employee with the given primaryKey cannot be found Method create (lines 19–20) creates new instances of the Employee EJB Method create throws a CreateException if there is a
problem with creating the EJB instance
12
13 // get Employee ID
15
16 // set social security number
19
20 // get social security number
23
24 // set first name
27
28 // get first name
30
31 // set last name
34
35 // get last name
Trang 36Method findByPrimaryKey is one type of finder method for entity EJBs Every
entity EJB must have a findByPrimaryKey method that takes the entity EJB’s
primary-key class as an argument Entity EJBs also can define additional finder methods A finder
method name must begin with findBy and should end with the name of property to be
used as the search criteria For example, a finder method for finding Employees based on the title property would be named findByTitle A finder method for finding
Employee s within a certain salary range would be named findBySalaryRange.
15.5 Employee EJB with Bean-Managed Persistence
This section describes the Employee EJB with bean-managed persistence and deploying the EJB This bean-managed implementation uses JDBC to store Employee data in an un-
derlying database
15.5.1 Employee EJB Implementation
Figure 15.3 shows the Employee EJB implementation using bean-managed persistence Class EmployeeEJB implements interface EntityBean (line 15) All entity EJB im- plementations must implement interface EntityBean Line 17 declares an Entity- Context reference for the EJB’s EntityContext The EntityContext provides the EJB with information about the container in which the EJB is deployed The Connec- tion object (line 18) is the EJB’s Connection to the Employee database Lines 20–
25 declare private member variables that cache data retrieved from the database and
up-dates from the client
14 // find Employee with given primary key
16 throws RemoteException, FinderException;
17
18 // create new Employee EJB
20 throws RemoteException, CreateException;
Fig 15.2 EmployeeHome interface for finding and creating Employee EJBs.
Trang 371 // EmployeeEJB.java
2 // EmployeeEJB is an entity EJB that uses bean-managed
3 // persistence to persist Employee data in a database.
17 private EntityContext entityContext;
18 private Connection connection;
19
21 private String socialSecurityNumber;
23 private String lastName;
25 private Double salary;
33 // set social security number
34 public void setSocialSecurityNumber( String number )
36 socialSecurityNumber = number;
39 // get social security number
40 public String getSocialSecurityNumber()
45 // set first name
46 public void setFirstName( String name )
48 firstName = name;
Fig 15.3 EmployeeEJB implementation of Employee remote interface using
bean-managed persistence (part 1 of 8)
Trang 3851 // get first name
52 public String getFirstName()
54 return firstName;
57 // set last name
63 // get last name
93 // create new Employee
94 public Integer ejbCreate( Integer primaryKey )
Fig 15.3 EmployeeEJB implementation of Employee remote interface using
bean-managed persistence (part 2 of 8)
Trang 39102 // create INSERT statement
103 String insert = "INSERT INTO Employee " +
113 // execute INSERT and close PreparedStatement
120 // throw EJBException if INSERT fails
121 catch ( SQLException sqlException ) {
122 throw new CreateException( sqlException.getMessage() );
123 }
124 } // end method ejbCreate
125
126 // do post-creation tasks when creating new Employee
127 public void ejbPostCreate( Integer primaryKey ) {}
128
129 // remove Employee information from database
130 public void ejbRemove() throws RemoveException
139 // create DELETE statement
140 String delete = "DELETE FROM Employee WHERE " +
150 // execute DELETE and close PreparedStatement
151 deleteStatement.executeUpdate();
152 deleteStatement.close();
Fig 15.3 EmployeeEJB implementation of Employee remote interface using
bean-managed persistence (part 3 of 8)
Trang 40154
155 // throw new EJBException if DELETE fails
156 catch ( SQLException sqlException ) {
157 throw new RemoveException( sqlException.getMessage() );
158 }
159 } // end method ejbRemove
160
161 // store Employee information in database
162 public void ejbStore() throws EJBException
171 // create UPDATE statement
172 String update = "UPDATE Employee SET " +
189 // execute UPDATE and close PreparedStatement
190 updateStatement.executeUpdate();
191 updateStatement.close();
193
194 // throw EJBException if UPDATE fails
195 catch ( SQLException sqlException ) {
196 throw new EJBException( sqlException );
197 }
198 } // end method ejbStore
199
200 // load Employee information from database
201 public void ejbLoad() throws EJBException
202 {
203 // get Employee record from Employee database table
204 try {
205
Fig 15.3 EmployeeEJB implementation of Employee remote interface using
bean-managed persistence (part 4 of 8)