Java Beans
Java Beans
Developer’s Guide
Borland ®
™
VERSION 5 JBuilder
Borland Software Corporation
100 Enterprise Way, Scotts Valley, CA 95066-3249
www.borland.com
Refer to the file DEPLOY.TXT located in the redist directory of your JBuilder product for a complete list of files that
you can distribute in accordance with the JBuilder License Statement and Limited Warranty.
Borland Software Corporation may have patents and/or pending patent applications covering subject matter in this
document. The furnishing of this document does not give you any license to these patents.
COPYRIGHT © 1997, 2001 Borland Software Corporation. All rights reserved. All Borland brand and product names
are trademarks or registered trademarks of Borland Software Corporation in the United States and other countries.
Other product names are trademarks or registered trademarks of their respective holders.
For third-party conditions and disclaimers, see the Release Notes on your JBuilder product CD.
Printed in the U.S.A.
JBE0050WW21002entjb 2E1R0401
0102030405-9 8 7 6 5 4 3 2 1
PDF
Contents
Chapter 1 Generating the bean class from a
remote interface . . . . . . . . . . . . . . . . . 3-11
An introduction to EJB development 1-1 Creating the home and remote interfaces
Why we need Enterprise JavaBeans . . . . . . . 1-1
for an existing bean . . . . . . . . . . . . . . . 3-13
Roles in the development of an EJB
Compiling the bean . . . . . . . . . . . . . . . . 3-16
application . . . . . . . . . . . . . . . . . . . . 1-2
Editing deployment descriptors. . . . . . . . . 3-18
Application roles . . . . . . . . . . . . . . . . 1-3
Infrastructure roles . . . . . . . . . . . . . . . 1-3
Deployment and operation roles . . . . . . . 1-4
Chapter 4
EJB architecture . . . . . . . . . . . . . . . . . . 1-4 Creating entity beans from an
The EJB server . . . . . . . . . . . . . . . . . 1-5 existing database table 4-1
The EJB container. . . . . . . . . . . . . . . . 1-5 Creating entity beans with the EJB
How an enterprise bean works . . . . . . . . 1-6 Entity Bean Modeler . . . . . . . . . . . . . . . 4-1
Types of enterprise beans . . . . . . . . . . . . . 1-7
Session beans . . . . . . . . . . . . . . . . . . 1-7 Chapter 5
Entity beans . . . . . . . . . . . . . . . . . . . 1-7 Testing an enterprise bean 5-1
Developing enterprise beans . . . . . . . . . . . 1-7 Creating a test client . . . . . . . . . . . . . . . . 5-1
Contacting Borland developer support . . . . . 1-8 Using the test client application . . . . . . . . . . 5-3
Online resources . . . . . . . . . . . . . . . . 1-9 Testing your enterprise bean. . . . . . . . . . . . 5-5
World Wide Web . . . . . . . . . . . . . . 1-9
Borland newsgroups . . . . . . . . . . . . 1-9 Chapter 6
Usenet newsgroups. . . . . . . . . . . . . 1-9 Deploying enterprise beans 6-1
Reporting bugs . . . . . . . . . . . . . . . 1-10 Creating a deployment descriptor file . . . . . . 6-2
Documentation conventions . . . . . . . . . . . 1-10 The role of the deployment descriptor . . . . . . 6-2
The types of information in the
Chapter 2 deployment descriptor . . . . . . . . . . . . 6-3
Setting up the target application Structural information. . . . . . . . . . . . 6-3
server 2-1 Application assembly information. . . . . 6-4
Adding application server files to Security . . . . . . . . . . . . . . . . . . . . 6-4
your project . . . . . . . . . . . . . . . . . . . . 2-3 Security roles . . . . . . . . . . . . . . . . . 6-4
Making the ORB available to JBuilder . . . . . . 2-3 Method permissions . . . . . . . . . . . . . 6-5
Selecting an application server . . . . . . . . . . 2-4 Linking of security role references . . . . . 6-5
Deploying to an application server . . . . . . . . 6-5
Chapter 3 Deploying one or more JAR files . . . . . . . 6-5
Deploying to WebLogic or WebSphere
Creating enterprise beans servers . . . . . . . . . . . . . . . . . . . . . 6-8
with JBuilder 3-1 Setting deployment options with
Creating an EJB group . . . . . . . . . . . . . . . 3-2 the Properties dialog box . . . . . . . . . . . 6-9
Creating an empty EJB group . . . . . . . . . 3-2 Hot deploying to an application server . . . . 6-9
Creating an EJB group from existing
enterprise beans. . . . . . . . . . . . . . . . 3-3 Chapter 7
Creating an enterprise bean. . . . . . . . . . . . 3-4 Using the Deployment
Creating a session bean . . . . . . . . . . . . 3-6
Creating an entity bean . . . . . . . . . . . . 3-6
Descriptor editor 7-1
Displaying the Deployment Descriptor
Adding the business logic to your bean . . . 3-8
editor . . . . . . . . . . . . . . . . . . . . . . . . 7-2
Exposing business methods through
Viewing the deployment descriptor of
the remote interface . . . . . . . . . . . . . 3-10
an enterprise bean. . . . . . . . . . . . . . . . . 7-2
i
Adding information for a new Chapter 9
enterprise bean . . . . . . . . . . . . . . . . . . 7-4
Changing bean information . . . . . . . . . . . 7-4
Developing session beans 9-1
Types of session beans . . . . . . . . . . . . . . . 9-1
Enterprise bean information . . . . . . . . . . . 7-4
Stateful session beans . . . . . . . . . . . . . . 9-1
Main panel . . . . . . . . . . . . . . . . . . . 7-4
Stateless session bean . . . . . . . . . . . . . . 9-2
Environment panel . . . . . . . . . . . . . . . 7-6
Writing the session bean class . . . . . . . . . . . 9-2
EJB references panel . . . . . . . . . . . . . . 7-8
Implementing the SessionBean
Security role references panel . . . . . . . . . 7-9
interface. . . . . . . . . . . . . . . . . . . . . 9-2
Resource references panel . . . . . . . . . . . 7-10
Writing the business methods . . . . . . . . . 9-3
Persistence panel . . . . . . . . . . . . . . . . 7-11
Adding one or more ejbCreate()
Finders panel . . . . . . . . . . . . . . . . . . 7-13
methods. . . . . . . . . . . . . . . . . . . . . 9-3
Properties panel . . . . . . . . . . . . . . . . 7-14
How JBuilder can help you create a
Container transactions . . . . . . . . . . . . . . 7-19
session bean . . . . . . . . . . . . . . . . . . 9-4
Adding a container-managed
The life of a session bean . . . . . . . . . . . . . . 9-5
transaction. . . . . . . . . . . . . . . . . . . 7-19
Stateless beans . . . . . . . . . . . . . . . . . . 9-5
Working with data sources . . . . . . . . . . . . 7-20
Stateful beans . . . . . . . . . . . . . . . . . . 9-6
Setting isolation levels . . . . . . . . . . . . . 7-22
The method-ready in transaction
Setting data source properties . . . . . . . . 7-22
state . . . . . . . . . . . . . . . . . . . . . 9-7
Adding security roles and method
A shopping cart session bean . . . . . . . . . . . 9-9
permissions . . . . . . . . . . . . . . . . . . . . 7-24
Examining the files of the cart example. . . . 9-9
Creating a security role . . . . . . . . . . . . 7-24
The Cart session bean . . . . . . . . . . . . . 9-10
Assigning method permissions . . . . . . . . 7-25
Adding the required methods . . . . . . 9-11
Viewing and editing WebLogic
Adding the business methods . . . . . . 9-12
and WebSphere properties . . . . . . . . . . . 7-26
Item class . . . . . . . . . . . . . . . . . . . . 9-14
Verifying descriptor information . . . . . . . . . 7-27
Exceptions . . . . . . . . . . . . . . . . . . . 9-14
Required interfaces . . . . . . . . . . . . . . 9-15
Chapter 8 The home interface . . . . . . . . . . . . 9-15
Using the DataExpress for The remote interface . . . . . . . . . . . . 9-16
EJB components 8-1 The Cart deployment descriptor . . . . . 9-17
The DataExpress EJB components . . . . . . . . 8-2
Components for the server . . . . . . . . . . 8-2 Chapter 10
Components for the client . . . . . . . . . . . 8-2 Developing entity beans 10-1
Creating the entity beans . . . . . . . . . . . . . 8-2 Persistence and entity beans . . . . . . . . . . . 10-1
Creating the server-side session bean . . . . . . 8-2 Bean-managed persistence . . . . . . . . . . 10-2
Adding provider and resolver Container-managed persistence . . . . . . . 10-2
components to the session bean. . . . . . . 8-3 Primary keys in entity beans. . . . . . . . . . . 10-3
Writing the setSessionContext() method. . . 8-4 Writing the entity bean class . . . . . . . . . . . 10-3
Adding an EJB reference to Implementing the EntityBean interface . . . 10-4
the deployment descriptor . . . . . . . . 8-4 Declaring and implementing the
Adding the providing and resolving entity bean methods. . . . . . . . . . . . . 10-5
methods . . . . . . . . . . . . . . . . . . . . 8-5 Creating create methods . . . . . . . . . 10-5
Calling the finder method . . . . . . . . . . . 8-6 Creating finder methods . . . . . . . . . 10-6
Building the client side . . . . . . . . . . . . . . 8-7 Writing the business methods . . . . . . 10-7
Handling relationships . . . . . . . . . . . . . . 8-9 Using JBuilder wizards to create an
The sample project . . . . . . . . . . . . . . . . . 8-9 entity bean . . . . . . . . . . . . . . . . . . 10-7
ii
The life of an entity bean . . . . . . . . . . . . . 10-8 Chapter 12
The nonexistent state. . . . . . . . . . . . . . 10-8
The pooled state . . . . . . . . . . . . . . . . 10-9
Developing enterprise bean clients 12-1
Locating the home interface . . . . . . . . . . . 12-2
The ready state . . . . . . . . . . . . . . . . . 10-9
Getting the remote interface . . . . . . . . . . . 12-2
Returning to the pooled state . . . . . . . . . 10-9
Session beans . . . . . . . . . . . . . . . . . 12-2
A bank entity bean example . . . . . . . . . . 10-10
Entity beans . . . . . . . . . . . . . . . . . . 12-3
The entity bean home interface . . . . . . . 10-10
Finder methods and the primary
The entity bean remote interface . . . . . . 10-11
key class . . . . . . . . . . . . . . . . . . 12-4
An entity bean with container-managed
Create and remove methods . . . . . . . 12-4
persistence. . . . . . . . . . . . . . . . . . 10-12
Calling methods. . . . . . . . . . . . . . . . . . 12-4
An entity bean with bean-managed
Removing bean instances . . . . . . . . . . . . 12-5
persistence. . . . . . . . . . . . . . . . . . 10-13
Referencing a bean with its handle . . . . . . . 12-6
The primary key class . . . . . . . . . . . . 10-18
Managing transactions . . . . . . . . . . . . . . 12-7
The deployment descriptor . . . . . . . . . 10-18
Discovering bean information . . . . . . . . . . 12-8
Deployment descriptor for an
Creating a client with JBuilder . . . . . . . . . 12-9
entity bean with bean-managed
persistence . . . . . . . . . . . . . . . . 10-20 Chapter 13
Deployment descriptor for an
entity bean with container-managed Managing transactions 13-1
persistence . . . . . . . . . . . . . . . . 10-20 Characteristics of transactions . . . . . . . . . . 13-1
Transaction support in the container . . . . . . 13-2
Chapter 11 Enterprise beans and transactions . . . . . . . 13-3
Bean- versus container-managed
Creating the home and remote transactions. . . . . . . . . . . . . . . . . . 13-3
interfaces 11-1 Transaction attributes . . . . . . . . . . . . . 13-4
Creating the home interface . . . . . . . . . . . 11-1 Local and global transactions . . . . . . . . 13-5
The EJBHome base class . . . . . . . . . . . . 11-2 Using the transaction API . . . . . . . . . . . . 13-6
Creating a home interface for a Handling transaction exceptions . . . . . . . . 13-7
session bean . . . . . . . . . . . . . . . . . . 11-2 System-level exceptions . . . . . . . . . . . 13-8
create() methods in session beans . . . . . 11-3 Application-level exceptions . . . . . . . . . 13-8
Creating a home interface for an Handling application exceptions . . . . . . 13-8
entity bean. . . . . . . . . . . . . . . . . . . 11-4 Transaction rollback . . . . . . . . . . . . 13-9
create() methods for entity beans . . . . . 11-4 Options for continuing a transaction . . 13-9
Finder methods for entity beans . . . . . 11-5
Creating the remote interface . . . . . . . . . . . 11-6 Index I-1
The EJBObject interface . . . . . . . . . . . . 11-7
iii
iv
Chapter
An introduction to EJB
Chapter1
1
development
The “Enterprise JavaBeans (EJB) specification” (http://java.sun.com/
products/ejb/docs.html) formally defines a Java server-side component
model and a programming interface for application servers. Developers
build the components, called enterprise beans, to contain the business
logic of the enterprise. Enterprise beans run on an EJB server that provides
services such as transaction management and security to the beans.
Developers don’t have to worry about programming these low-level and
complex services, but can focus on encapsulating the business rules of an
organization or system within the beans, knowing that the services are
available to the beans when they are needed.
While the Enterprise JavaBeans specification is the ultimate authority on
the EJB framework, it’s primarily useful to vendors such as Borland who
build the EJB servers and containers the beans run in. This book will help
you, the JBuilder developer, learn what you want to know about
developing enterprise beans and creating applications that use them.
If you are already familiar with EJB development and want to get started
creating enterprise beans with JBuilder, start with Chapter 3, “Developing
enterprise beans.”
data, these applications don’t scale well to meet the demands. Because the
client contains the logic, it must be installed on each machine.
Management becomes increasingly difficult.
Gradually the benefits of dividing applications into more than the two
tiers of the client-server model becomes apparent. In a multi-tier
application, only the user interface stays on local machines while the logic
of the application runs in the middle tier on a server. The final tier is still
the stored data. When the logic of an application needs updating, changes
are made to the software of the middle tier on the server, greatly
simplifying the management of updates.
But creating reliable, secure, and easily managed distributed applications
is notoriously difficult. For example, managing transactions over a
distributed system is a major task. Fortunately, using components that
follow the EJB specification to build distributed systems relieves much of
the burden by:
• Dividing the development of a distributed system into specific tasks
that are assigned to specialists.
For example, if the application is an accounting system, the enterprise
bean developer would need to understand accounting. The system
administrator must know about monitoring a deployed and running
application. Each specialist assumes a particular role.
• Making EJB server and container services available to the enterprise
bean and application developers.
The EJB server provider and EJB container provider (who are often the
same vendor) handle many of the more difficult tasks so the developers
don’t have to. For example, the container an enterprise bean runs in can
provide transaction and security services to the bean automatically.
• Making enterprise beans portable.
Once a bean is written, it can be deployed on any EJB server that
adheres to the Enterprise JavaBeans standard. Each bean is likely to
include vendor-specific elements, however.
Application roles
Those who assume the application roles write the code for the enterprise
beans and the applications that use them. Both roles require an
understanding of how the business runs, although at different levels.
These are the two application roles:
• Bean provider
Bean providers (also called bean developers) create the enterprise
beans and write the logic of the business methods within them. They
also define the remote and home interfaces for the beans and they
create the beans’ deployment descriptors. Bean providers don’t
necessarily need to know how their beans will be assembled and
deployed.
• Application assembler
Application assemblers write the applications that use the enterprise
beans. These applications usually include other components, such as
GUI clients, applets, JavaServer Pages pages (JSP), and servlets. These
components are assembled into a distributed application. Assemblers
add assembly instructions to the bean deployment descriptors.
Although application assemblers must be familiar with the methods
contained within the enterprise beans so they can call them, they don’t
need to know how those methods are implemented.
JBuilder users who are interested in Enterprise JavaBeans are usually bean
providers and application assemblers. Therefore, this book is written
primarily for them. JBuilder has wizards, designers, and other tools that
simplify the development of enterprise beans and the applications that
use them.
Infrastructure roles
Without a supporting infrastructure, the enterprise beans and the
applications that use them cannot run. Although the two infrastructure
roles are distinct, they are almost always assumed by the same vendor.
Together they provide system-level services to the enterprise beans and
provide an environment in which to run. These are the two infrastructure
roles:
• EJB server provider
EJB server providers are specialists in distributed transaction
management, distributed objects, and other low-level services. They
provide an application framework in which to run EJB containers. EJB
service providers must provide, at a minimum, a naming service and a
transaction service to the beans.
EJB architecture
Multi-tier distributed applications often consist of a client that runs on a
local machine, a middle-tier that runs on a server that contains the
business logic, and a backend-tier consisting of an enterprise information
system (EIS). An EIS can be a relational database system, an ERP system, a
legacy application, or any data store that holds the data that needs to be
accessed. This figure shows a typical EJB multi-tier distributed system
with three tiers: the client; the server, the container, and the beans
deployed on them; and the enterprise information system.
Because our interest is how to develop enterprise beans, our focus is the
middle tier.
The EJB server and EJB container together provide the environment for
the bean to run in. The container provides management services to one or
more beans. The server provides services to the bean, but the container
interacts on behalf of the beans to obtain those services.
Although it is a vital part of the Enterprise JavaBeans architecture,
enterprise bean developers and application assemblers don’t have to think
about the container. It remains a behind-the-scenes player in an EJB
distributed system. Therefore, this book goes no further explaining what a
container is and how it works. For more information about containers,
refer to the “Enterprise JavaBeans 1.1 Specification” itself (http://
java.sun.com/products/ejb/docs.html). For specific information about
the Borland EJB container, see the Borland AppServer’s Enterprise JavaBeans
Programmer’s Guide.
Session beans
An enterprise session bean executes on behalf of a single client. In a sense,
the session bean represents the client in the EJB server.
Session beans can maintain the client’s state, which means they can retain
information for the client. The classic example where a session bean might
be used is a shopping cart for an individual shopping at an online store on
the web. As the shopper selects items to put in the “cart,” the session bean
retains a list of the selected items.
Session beans can be short-lived. Usually when the client ends the session,
the bean is removed by the client.
Session beans can be either stateful or stateless. Stateless beans don’t
maintain state for a particular client. Because they don’t maintain
conversational state, stateless beans can be used to support multiple
clients.
Entity beans
An entity bean provides an object view of data in a database. Usually the
bean represents a row in a set of relational database tables. An entity bean
usually serves more than one client.
Unlike session beans, entity beans are considered to be long-lived. They
maintain a persistent state, living as long as the data remains in the
database, rather than as long as a particular client needs it.
The container can manage the bean’s persistence, or the bean can manage
it itself. If the persistence is bean-managed, the bean developer must write
code that includes calls to the database.
start reading Chapter 9, “Developing session beans” and the chapters that
follow it before beginning this chapter.
Developing Enterprise JavaBeans with JBuilder has several steps:
1 Setting up the target application server (see Chapter 2)
2 Creating an EJB group (see page 3-2)
3 Creating an enterprise bean and its home and remote interfaces (see
page 3-4)
4 Compiling the bean (see page 3-16)
5 Editing the deployment descriptor (see page 3-18)
6 Creating a test client application (see page 5-1)
7 Testing your enterprise bean (see page 5-5)
8 Deploying to an application server (see page 6-5)
You can also use JBuilder to create entity enterprise beans based on
existing tables in any database accessible through JDBC. See “Creating
entity beans with the EJB Entity Bean Modeler” on page 4-1.
If you prefer to create the remote interface for an enterprise bean first, you
can then use the EJB Bean Generator to create a skeleton bean class and
home interface based on that remote interface. For more information, see
“Generating the bean class from a remote interface” on page 3-11.
Online resources
You can get information from any of these online sources:
World Wide Web http://www.borland.com/
FTP ftp.borland.com
Technical documents available by anonymous ftp.
Listserv To subscribe to electronic newsletters, use the online form at:
http://www.borland.com/contact/listserv.html
or, for Borland’s international listserver,
http://www.borland.com/contact/intlist.html
Borland newsgroups
You can register JBuilder and participate in many threaded discussion
groups devoted to JBuilder.
You can find user-supported newsgroups for JBuilder and other Borland
products at http://www.borland.com/newsgroups/
Usenet newsgroups
The following Usenet groups are devoted to Java and related programming
issues:
• news:comp.lang.java.advocacy
• news:comp.lang.java.announce
• news:comp.lang.java.beans
• news:comp.lang.java.databases
• news:comp.lang.java.gui
• news:comp.lang.java.help
• news:comp.lang.java.machine
• news:comp.lang.java.programmer
• news:comp.lang.java.security
• news:comp.lang.java.softwaretools
Note These newsgroups are maintained by users and are not official Borland sites.
Reporting bugs
If you find what you think may be a bug in the software, please report it in
the JBuilder Developer Support page at http://www.borland.com/
devsupport/jbuilder/. From this site, you can also submit a feature
request or view a list of bugs that have already been reported.
When you report a bug, please include all the steps needed to reproduce
the bug, including any special environmental settings you used and other
programs you were using with JBuilder. Please be specific about the
expected behavior versus what actually happened.
If you have comments (compliments, suggestions, or issues) with the
JBuilder documentation, you may email [email protected]. This is for
documentation issues only. Please note that you must address support
issues to developer support.
JBuilder is made by developers for developers. We really value your
input, because it helps us to improve our product.
Documentation conventions
The Borland documentation for JBuilder uses the typefaces and symbols
described in the table below to indicate special text.
4 Select the appropriate library. For example, if your target is the Borland
AppServer, select the BAS 4.5 library and click OK twice to close the
dialog boxes.
command to start the SmartAgent to the Tools menu, check the Add The
VisiBroker SmartAgent Item To The Tools Menu option.
You must still perform one step: starting the VisiBroker SmartAgent. This
handles the initial bootstrap issues such as how the client locates the
naming service and so on.
To start the SmartAgent, choose Tools|VisiBroker SmartAgent.
4 Select the application server you are building your beans to run on. The
Borland AppServer 4.5 is the default server.
The EJB 1.1 choice is a generic option. Select it if the application server
you use is not currently supported by JBuilder. You will probably want
to edit the resulting deployment descriptor with tools supplied with
that application server to get the exact settings you want. You could
also choose this option if the you aren’t targeting a specific application
server.
5 Choose OK to close the dialog box.
You can have more than one EJB group in a project. All the EJB groups in a
single project use the same project classpath and JDK, and they are
configured for the same target application server.
If you haven’t done so already, follow the instructions in Chapter 2,
“Setting up the target application server.” You must follow the steps to
add a library containing your application server files to each EJB project
you undertake.
5 Specify the name of the JAR file your enterprise bean(s) will be in.
JBuilder entered a default name that is the same as the name of your
EJB group. You can simply accept that name or specify another.
JBuilder also entered a path based on your project path. You can change
it to your liking or accept the default path.
6 Click OK to create the EJB group.
6 Click Next and specify the directory that contains the existing
deployment descriptor(s) you want to make up the group. When you
do, the wizard lists the deployment descriptors in the specified
directory in the Usable Descriptors Found field.
7 Click Finish to create the EJB group that contains the deployment
descriptors for the existing bean(s).
3 In the drop-down list, select the EJB group you want your enterprise
bean to belong to. Choose Next to display page 2 of the wizard.
If you don’t have an EJB group defined before you start the Enterprise
JavaBeans wizard or you want to create another, click the New button
to start the Empty EJB Group wizard. You must have at least one EJB
group defined in your project before you can create an enterprise bean.
Once you’ve created an EJB group with the Empty EJB Group wizard,
select the new group and choose Next to continue with the Enterprise
JavaBean wizard.
4 Specify the class name of your bean class, the package it will be in, and
the bean’s base class.
Next you must decide whether you are creating a session bean or an entity
bean.
4 Specify names for the Home Interface Class, the Remote Interface Class,
and the Bean Home Name; JBuilder suggests default names based on
the name of your bean class.
5 Click Finish.
4 Specify names for the Home Interface Class, the Remote Interface Class,
and the Bean Home Name; JBuilder suggests default names based on
the name of your bean class.
5 Click Finish.
After you click the Finish button, JBuilder creates the bean class and its
home and remote interfaces. You’ll see them appear in the project pane.
Examine the source code of the bean class and you’ll see that the class
implements the SessionBean interface if it’s a session bean, and it
implements the EntityBean interface if it’s an entity bean. JBuilder has
added methods with empty bodies for the methods all enterprise beans
must implement. You can add code to these method bodies to supply the
logic your bean requires when these methods are called.
The home interface extends the EJBHome interface and contains a create()
method needed to create the bean. The remote interface extends EJBObject
but is empty otherwise because you have yet to declare any business logic
methods for your bean.
Although you can begin your entity beans using the Enterprise JavaBeans
wizard, the preferred way to create entity beans is to use the EJB Entity
Bean Modeler. Entity beans you create with the Enterprise JavaBean
wizard aren’t likely to pass verification with the Deployment Descriptor
editor until you complete the bean more fully.
As you check methods in the Methods box, the methods are added to the
remote interface.
To remove a method from the remote interface, uncheck the check box
next to the method in the Methods box.
To edit one of the methods, right-click it to display a context menu and
choose Edit Selected. The file opens in the code editor and your cursor is
positioned on that method, ready for you to edit it.
The context menu has other commands you’ll find useful. You can choose
Remove Selected to remove a method from the bean class. Choosing
Check All checks all the methods so that they are all added to the remote
interface; choosing Uncheck All unchecks all the methods so that no
methods are added to the remote interface.
You can use the Methods page to verify that the methods declared in your
bean class have the same method signature as they do in the home and
remote interface. For example, suppose you add a parameter to the
ejbCreate() method in your bean class, but neglect to add it to the create()
method in the home interface. The Methods box will show both the
ejbCreate() method and create() method in red text. If you then click a
method displayed in red text, the Problem Description box explains what
the problem is. You could then add the additional parameter to the
create() method to make the method signatures match and fix the
problem. Or, if you remove methods from your bean class but forget to do
so in the remote interface, the Methods box will display those methods in
red text to remind you to remove them from the remote interface.
3 Select the EJB group the bean belongs to and click Next.
4 Select the type of EJB you want generated and click Next.
If you selected one of the session bean options, this page appears:
• Specify the EJB Bean options: the Bean Class, the Bean Name, the
Home Interface, and the JNDI Name.
If you selected one of the CMP entity bean options, this screen appears:
• Specify the EJB Bean options: the Bean Class, the Bean Name, the
Home Interface, the JNDI Name, the Primary Key Class, and which
fields you want to be persistent.
5 Choose Finish.
The EJB Bean Generator creates the skeleton bean class you specified
that includes the methods found in the remote interface. In the
generated bean class, these methods include a comment reminding you
to fill in their implementations. You must add your code to the
methods to implement them as you wish.
The EJB Bean Generator also creates a home interface if one did not
previously exist. If a home interface did exist, the EJB Bean Generator
asks you if you want to overwrite the home interface and responds
according to your answer.
3 Select the EJB group the bean belongs to and click Next.
This page appears if the bean is a session bean:
7 Leave those methods that you want exposed in the remote interface
checked and uncheck those you don’t want to appear in the remote
interface.
8 Choose Finish.
You can also insert deployment descriptors into an EJB group and copy
deployment descriptors to elsewhere. You can also delete a deployment
descriptor.
If you want to specify that additional files should be added to the JAR
file, click the Add Button and specify the location of the files. You’ll
need to do this if you’ve added a new class to your project, for example,
and you want it to become part of the JAR file. Or if you have
deployment descriptors you have edited outside of JBuilder, you can
add them here and uncheck the Include Deployment Descriptors In
Output JAR File. The deployment descriptors shown in the
Deployment Descriptors In Group list won’t be added to the JAR, but
those you specified in the Additional Files For META-INF In JAR list
will be.
If you might target different application servers, you can use the
Remove Stubs Files On Application Server Change option to remove
client stubs used by the old application server when you select a new
application server.
The Always Create JAR When Building option is on by default. By
unchecking this option, you can defer building the JAR file until you
are ready to begin testing.
5 Click OK the tab of the application server you are targeting. For
example, this image shows the BAS 4.5 tab selected:
6 Specify the build options you want. If you need more information
about the available options, click the Help button.
You can also modify the build properties for each bean instead of for the
whole EJB group:
1 Right-click the home interface of the bean and choose Properties.
2 Click the Build tab.
3 Click the VisiBroker tab.
4 Check the Generate IIOP check box and select any other Java2IIOP
options you want.
5 Click OK.
To compile all the classes in the project, right-click the project file
(<project>.jpx) and choose Make, or simply choose Project|Make Project.
During the compiling process, JBuilder might detect that a problem exists in a
deployment descriptor that makes it invalid. If this happens, you’ll see a
message appear in the message pane that tells you to verify the bean in the
Deployment Descriptor editor. For more information about verifying a
deployment descriptor, see “Verifying descriptor information” on page 7-27.
Note for WebLogic users. If you are targeting the WebLogic Server, you’ll
receive an error during the build process if the temporary directory or the
classpath contains embedded spaces, such as C:/Documents and
Settings/jbprojects.
If you’ve chosen to generate the clients stubs, you’ll see that the home
interface node in the project pane now has several files listed below it if
you click its icon to expand it. These generated files are the required client
stubs and helper classes that make EJB work.
Note that the EJB Properties tab does not appear if your target application
server is the Borland AppServer or the Inprise Application Server. The EJB
Properties page allows you to change values for WebLogic or WebSphere
application servers.
For detailed information about using the Deployment Descriptor editor,
see Chapter 7, “Using the Deployment Descriptor editor.”
After you’ve finished editing the descriptor, you can verify the file to
make sure the descriptor information correct, the required bean class files
are present, and so on.
To verify descriptor information, click the Verify button on the
Deployment Descriptor editor’s tool bar.
Verify does the following:
• Ensures that the descriptor conforms to the EJB 1.1 specification.
• Ensures that the classes referenced by the deployment descriptors
conform to the EJB 1.1 specification.
If the verification fails, one or more messages appear in a Log panel
describing the failures.
To display the EJB Entity Modeler, choose File|New, click the Enterprise
tab, and choose EJB Entity Bean Modeler. If you have at least one EJB
group defined in your project, the Entity Bean Modeler appears.
5 Select the columns from each table to map to entity bean fields and
specify any relationships you want to establish between the tables.
In the Tables and Links section, you’ll see all the tables you selected in
the previous step. Select each table in turn by clicking on it and then use
the Selected Table’s Columns section to move any columns of the table
between the Available and Selected lists. By default, all columns in
every table are selected.
You can also specify relationships between the tables by dragging the
mouse pointer between the tables in the Tables and Links box on the
left. Or you can use the Add Link button to do the same thing. When
you use either method, a dialog box appears that proposes a
relationship based on foreign keys, primary keys, unique indexes, and
field names and types in the two tables. You can accept the suggested
relationship or modify it to create the relationship you want. To remove
a link between tables, choose Remove Link.
When you’ve selected all columns in each table that you want mapped
to fields in entity beans you’re creating, choose Next.
6 Specify the names and data types for the entity bean fields to map to
your table’s columns.
Click the appropriate tab to select the table you want to begin the
mapping process on. For each column in the table a suggested Field
Name and Field Type appears. You can simply accept the suggested
name or edit the suggested names and types as you want them to be in
your bean.
To change the data type of multiple fields at one type, select the fields
you want to change and choose Update Field Type. A dialog box
appears in which you can type the new field type. When you choose
Apply or OK, the field type for each selected field changes.
If the table already has a primary key, that field or set of fields is
selected when the Map Columns page first appears. If no primary key
exists, you must select one or more fields to make up primary key by
checking the check box for those fields in the Primary Key column.
When you finish mapping all the selected columns to the field names
and types you want in your entity bean for each table, choose Next.
7 Specify the package, the classes and interfaces, and the JNDI name for
each bean you are creating.
For each table, JBuilder suggests a name for the entity bean, the name
used by JNDI, the name of the home and remote interfaces, the name of
the bean class, and the type of the primary key class. You can specify a
different package for each of these; by default, the project package is
suggested. You can accept these values as they are, or you can modify
them as you wish. When you have finished specifying the information
for each table, choose Next.
also includes a Pool Name field in which you should enter the name of
the pool for your CMP WebLogic beans:
9 Choose Finish.
JBuilder creates an entity bean for each table and all the supporting classes
interfaces. You can now add the business logic you want to the beans,
define the methods you want the client to be able to call in the remote
interface, compile the beans, and edit the deployment descriptors for the
beans.
3 Select the bean you want to create a client for using one of the Select EJB
options and specifying the bean:
• Select From Project if your bean is in the current project and specify
which bean by selecting it from the drop-down list.
• Select From JAR Or Directory if your bean is not in the current
project, but exists elsewhere in a JAR file or a directory. Use the ...
button to navigate to where the JAR is located and select the JAR,
then use the drop-down list to select the bean you want.
4 Select the package name from the list of packages. The current package
is the default value.
5 Enter a name for the test client class or accept the default name.
6 Select the options you want:
• Generate Method For Testing Remote Interface Calls With Default
Arguments
Adds a testRemoteCallsWithDefaultArguments() method that tests the
remote interface calls with default argument values. For example,
the default argument for a String is “”, the default argument for an
int is 0, and so on.
• Generate Logging Messages
Adds code that displays messages reporting on the bean’s status as
the client runs. For example, a message is displayed when bean
initialization is begun and another when it completes. This option
also generates wrappers for all the methods declared in the home
and remote interfaces and initialization functions. Finally, the
messages report how long each method call takes to complete.
• Generate Main Function
Adds the main function to the client.
• Generate Header Comments
Adds JavaDoc header comments to the client you can use to fill in
information such as title, author, and so on.
7 Choose OK.
The EJB Test Client wizard generates a test client that creates a reference to
the enterprise bean.
3 If the test client already exists, check the EJB Test Client Class Already
Exists option.
If this option isn’t checked, when you click Next, the EJB Test Client
wizard starts. When you are through using it, the Use EJB Test Client
wizard resumes.
4 Click Next to go to Step 2.
5 For the Class field, navigate to the test client class you want to use.
6 In the Field field, specify a name for the variable that will hold an instance
of the test client class, or accept the default value the wizard suggests.
7 Choose Finish.
The wizard adds a declaration of the test client application you specified
to the class like this, for example:
EmployeeTestClient1 employeeTestClient1 = new EmployeeTestClient1();
Now you’re ready to call the methods declared in the test client application.
2 Click the New button and then click the EJB tab.
The container starts up. Be patient as the start-up process takes a while.
You can view the progress of the start-up process in the message window.
Any errors that occur will also appear there.
Next select the Client run configuration to run your client application. The
messages that appear in the message pane report the success or failure of
the client application’s execution.
Another way to test your bean is to simply right-click its EJB group in the
project pane and choose Run.
You can debug your enterprise beans or the client just as you would any
other Java code with JBuilder. For information about debugging, see
“Debugging Java programs” in Building Applications with JBuilder.
Structural information
The bean developer must provide the following structural information for
each bean in the EJB jar:
Session beans
• Session bean state management type, either stateful or stateless
• Session bean transaction demarcation type for stateful beans that have
synchronization callbacks
Entity beans
• Entity bean’s persistence management type
• Entity bean’s primary key class
• Container-managed fields for container-managed beans
Security
The application assembler usually specifies the following information in
the deployment descriptor:
• Security roles
• Method permissions
• Links between security role references and security roles
Security roles
Using the security role elements in the deployment descriptor, the
developer can define one or more security roles. These define the required
security roles for the clients of the enterprise beans.
Method permissions
Using the method-permission elements in the deployment descriptor, the
developer can define method permissions. Method permissions are paired
relations between the security roles and the methods of the enterprise
bean’s remote and home interfaces.
2 Specify the JAR file(s) that contain the beans you want to deploy.
If you want to deploy additional JARs, click the Add button and specify
the JARs you want added. To remove a JAR from the list, select and
click Remove. You also have access to the BAS 4.5 Archive Tool and the
Deployment Descriptor editor in this step.
3 Click Next to go to the next step.
5 Click Next if there are no errors reported, otherwise fix any errors and
begin again.
6 Use this page to select the container you want to deploy your EJB.
In this example, the user clicked the Add EJB Container button to select
a container:
The wizard attempts to deploy the EJB and reports the results.
7 Click Finish to close the wizard.
Fill in the fields you need and choose OK. For more information, click the
Help button in the Deploy Settings dialog box.
Note that a tree of the EJB group appears in the structure pane.
You can click any of these tabs at the bottom of the Deployment
Descriptor editor to view other pages. Use the editor to make any changes
you want to the deployment information for the bean.
You can view additional information about a deployment descriptor by
using the structure pane:
Main panel
Use the Main panel to enter or change general information about the
enterprise bean.
For Session beans, the Main panel also includes the following:
• Session Type: Specifies whether the enterprise bean is Stateless or
Stateful.
• Transaction Type: Specifies whether Transaction Policies are set by the
bean or the Container.
For Entity beans, the Main panel also includes the following:
• Primary Key Class: The fully-qualified name of the Entity bean’s
primary key class. The primary key class must be specified.
• Reentrant: Indicates the bean is reentrant. Borland recommends you
avoid making a bean reentrant.
Environment panel
The Environment panel lists all the enterprise bean’s environment entries.
Environment entries allow you to customize the bean’s business logic
when the bean is assembled or deployed. The environment allows you to
customize the bean without accessing or changing the bean’s source code.
Each enterprise bean defines its own set of environment entries. All
instances of an enterprise bean share the same environment entries.
Enterprise bean instances aren’t allowed to modify the bean’s
environment at runtime.
To remove a row,
1 Select the row.
2 Click the Remove button.
These are some things to keep in mind about the environment entries:
• The bean provider must declare all the environment entries accessed
from the enterprise bean’s code.
• If the bean provider includes a value for the environment entry, the
value can be later changed during the assembly or deployment.
• The assembler can modify the values of the environment entries set by
the bean provider.
• The deployer must ensure that the values of all environment entries are
set to meaningful values.
Before you can add a security role reference, one or more security roles
must be already defined or the Add button on this panel is disabled. For
information about creating and assigning security roles for application
deployment, see “Adding security roles and method permissions” on
page 7-24.
To add a role, click the Add button and fill in the three fields:
• Description: This is an optional field that describes the security role.
• Role: This is the name of the security role specified by the bean
developer.
• Link: This is the name of the security role used when the application is
deployed. Usually, this role is defined by the application assembler or
deployer to work in a specific operating environment.
To add a resource reference, click the Add button and fill in the following
fields:
• Description: A description of the resource reference. This information
is optional.
• Name: The name of the environment entry used in the enterprise
bean’s code.
• Type: The Java type of the resource factory expected by the enterprise
bean’s code. (This is the Java type of the resource factory, not the Java
type of the resource.)
• Authentication: An Application authentication indicates that the
enterprise bean performs the resource sign-on programmatically. A
Container authentication indicates that the container signs on to the
resource based on the principal mapping information supplied by the
deployer.
• JNDI Name: JNDI name for the resource reference.
• CMP (container-managed persistence): If you’re using
container-managed persistence for the bean, you must have one (and
only one) resource reference with the CMP field checked.
Persistence panel
The Persistence panel appears only for entity beans. It specifies how
persistence is managed for the enterprise bean. Information displayed on
the panel varies depending on whether persistence is bean-managed or
container-managed.
Finders panel
The Finders panel specifies the “where” clauses used by the
container-managed bean to execute finder methods defined by the bean.
Here’s an example:
Properties panel
The Properties panel contains varying information depending upon the
context. When you select an enterprise bean in the structure pane, the
following Properties pane appears:
ejb.cmp.primaryKeyGenerator
Specifies a class, written by the user, that implements the
com.inprise.ejb.cmp.PrimaryKeyGenerator interface and generates primary
keys. For more information about primary key generation, see the
/Borland/AppServer/examples/ejb/pkgen example.
ejb.cmp.getPrimaryKeyBeforeInsertSql
Specifies the SQL the CMP engine executes to generate a primary key
when the next INSERT occurs. The CMP engine updates the entity bean
with this primary key value. This property is usually used in
conjunction with Oracle Sequences. For more information about
primary key generation, see the /Borland/AppServer/examples/ejb/pkgen
example.
ejb.cmp.getPrimaryKeyAfterInsertSql
Specifies the SQL the CMP engine executes to generate a primary key
after the next INSERT. The CMP engine updates the entity bean with
this primary key value. When specifying this property, you must also
specify the ejb.cmp.ignoreColumnsOnInsert property. For more
information about primary key generation, see the
/Borland/AppServer/examples/ejb/pkgen example.
ejb.cmp.ignoreColumnsOnInsert
Specifies the name of the column the CMP must not set during the
INSERT. This property is used in conjunction with the
ejb.cmp.getPrimaryKeyAfterInsertSql property. For more information
about primary key generation, see the
/Borland/AppServer/examples/ejb/pkgen example.
ejb.cmp.checkExistenceBeforeCreate
Suppresses the existence check that occurs before creating a new entity
bean. The EJB 1.1 specification requires that the container first check for
the existence of an entity bean (that is, check for the existence of a row
in the table) and throw a javax.ejb.DuplicateKeyException if such an
entity is found. For performance reasons, you might want to eliminate
this extra access to the database and rely on the fact that the database
will prevent duplicate values from being inserted.
ejb.cmp.jdbcAccesserFactory
Specifies a factory for a user-implemented instance of the
com.inprise.ejb.cmp.JdbcAccessor interface. This interface gives you a
way to write specific code to get a value from a java.sqlResultSet or to
set a value to a java.sql.PreparedStatement. The default value is none.
ejb.cmp.manager
Specifies the name of a class implementing the interface
com.inprise.ejb.cmp.Manager. An instance of this class is used to perform
container-managed persistence (CMP).
ejb.maxBeansInPool
Specifies the maximum number of beans in the ready pool. If the ready
pool exceeds this limit, entities will be removed from the container by
calling unsetEntityContext(). The default setting is 1000.
ejb.maxBeansInCache
Specifies the maximum number of beans in the Option A cache (see
ejb.transactionCommitMode which follows). If the cache exceeds this
limit, entities will be moved to the ready pool by calling ejbPassivate().
The default setting is 1000.
ejb.transactionCommitMode
Indicates the disposition of an entity bean with respect to a transaction.
The values are:
• A or Exclusive—This entity has exclusive access to the particular
table in the database. Thus, the state of the bean at the end of the last
committed transaction can be assumed to be the state of the bean at
the beginning of the next transaction. The beans are cached across
transactions.
• B or Shared—This entity shares access to the particular table in the
database. However, for performance reasons, a particular bean
remains associated with a particular primary key between
transactions to avoid extraneous calls to ejbActivate() and
ejbPassivate() between transactions. The bean stays in the active
pool. This setting is the default.
• C or None—This entity shares access to the particular table in the
database. A particular bean does not remain associated with a
particular primary key between transactions, but goes back to the
ready pool after every transaction. This is generally not a useful
setting.
ejb.cmp.optimisticConcurrencyBehavior
You can specify one of the following:
• UpdateAllFields
• UpdateModifiedFields
• VerifyModifiedFields
• VerifyAllFields
• UpdateAllFields - Issues an update on all fields, regardless of
whether they were modified. Given a CMP bean with three fields:
“key”, “value1” and “value2”, stored in a table called “MyTable”,
the following update will be issued at the end of every transaction,
regardless of whether the bean was modified:
UPDATE MyTable SET (value1 = <value1>, value2 = <value2>)
WHERE key = <key>
• UpdateModifiedFields -This is the default setting. Issues an update
only on the fields that were modified, or suppresses the update
altogether if the bean was not modified. With the above bean, if only
“value1” was modified, the following update is issued:
UPDATE MyTable SET (value1 = <value1>)
WHERE key = <key>
This can give a significant performance boost for following reasons:
1 Very often your data access is read-only. In such cases, not
sending an update to the database is desirable. Borland have seen
great performance boosts from this single optimization.
2 Many databases write logs depending on which columns were
modified. For example, SQL Server will log the update if a TEXT
or IMAGE field is updated, regardless of whether the column’s
value actually changed. Note that the database often does not (or
cannot) distinguish between updating a column to hold the same
value it used to hold (which is what occurs with
“UpdateAllFields”), and actually modifying the column’s value.
Suppressing the update for the case where the value did not
actually change can have a very significant performance impact
when using such DBMSs.
3 There is less JDBC-based network traffic going to the database
and less work going on in the JDBC driver. The network issue is,
generally, not significant, but the JDBC driver issue is significant.
Our performance measurements indicate that as many as 70% of
the CPU’s time is spent in the JDBC driver in large-scale EJB
applications. Often, this is due to the fact that many commercial
JDBC drivers have not been sufficiently performance tuned. Even
for well-tuned drivers, the less work they have to do, the better.
ejb.findByPrimaryKeyBehavior
Indicates the desired behavior of the findByPrimaryKey() method. The
values are:
• Verify - The standard behavior for findByPrimaryKey() is to verify that
the specified primary key exists in the database.
• Load - This behavior causes the bean’s state to be loaded into the
container when findByPrimaryKey() is invoked, if the finder call is
running in an active transaction. The assumption is that found
objects will typically be used, and it is optimal to load the object’s
state at find time. This setting is the default.
• None - This behavior indicates that findByPrimaryKey() should be a
no-op. Basically, this causes the verification of the bean to be
deferred until the object is actually used. Since it is always the case
that an object could be removed between calling find and actually
using the object, for most programs this optimization will not cause
a change in client logic.
For information about the Properties panel in other contexts, see “Setting
data source properties” on page 7-22 and “Assigning method
permissions” on page 7-25.
Container transactions
Enterprise beans that use container-managed transactions must have the
transaction policies set by the container. The Deployment Descriptor
editor enables you to set container-managed transaction policies and then
associate these policies with methods in the enterprise bean’s home and
remote interfaces.
Property Description
uniqueSequence Determines whether the CMP engine should declare a
unique sequence for the primary key columns. Usually
this is achieved by declaring the appropriate columns
to be primary keys (see primaryKeyDeclaration).
batchUpdates Indicates whether the CMP engine should batch
updates to the database. This can have a significant
performance benefit for transactions that update a
number of entities that update a number of entities,
and should be used if the driver supports it.
Unfortunately, most don’t support batch updates yet.
The default value is false.
Property Description
reuseStatements Determines whether the CMP engine should reuse
prepared statements across transactions. Reusing
prepared statements has a significant performance
impact, and they should be used unless the JDBC
driver exhibits are reused. The default value is true.
notNullDeclaration Determines whether the Java fields that can’t be null
(such as int or float) should map to non-null columns.
The default value is true.
dialect Determines the type of the data source, such as
whether its a JDataStore, Oracle, Informix, or other
data source. Select the dialect value from the Value
drop-down list. If you don’t set this field, the CMP
engine creates tables for JDataStore only. The default
value is none.
primaryKeyDeclaration Determines whether the CMP engine declares the
primary key columns in the table to be primary keys.
Some databases don’t support primary key
declarations. The default value is true.
The new role appears under the Security Roles node in the structure pane.
If you don’t see it, be sure to expand the Security Roles node. Also, a
Properties panel for the role appears:
You can enter a description for the new role on the Properties panel. The
description is optional.
You can use this table to view the property values or to edit them. Use the
left column to enter values for properties you want to modify. The
property values are stored in the application server-specific deployment
descriptors.
To the members of this class, add a reference to the home interface of the
entity bean that contains the data you want to access. For this example, the
reference is to the home interface of the Employee entity bean as shown here
in bold.
public class PersonnelBean implements SessionBean {
private SessionContext sessionContext;
EntityBeanProvider entityBeanProvider = new EntityBeanProvider();
EntityBeanResolver entityBeanResolver = new EntityBeanResolver();
TableDataSet employeeDataSet = new TableDataSet();
EmployeeHome employeeHome;
...
5 Enter a reference name. For the sample project, the name is ejb/Employee.
6 Check the IsLink check box.
7 Specify the entity bean from the Link drop-down list.
The rest of the data should fill in for you automatically.
...
void entityBeanProvider_findEntityBeans(EntityBeanFindEvent e) {
}
3 To the new event handler, add a finder method to return the entity
beans you want. Here the added code appears in bold:
void entityBeanProvider_findEntityBeans(EntityBeanFindEvent e) {
try {
e.setEntityBeanCollection(employeeHome.findAll());
}
catch (Exception ex) {
throw new EJBException(ex);
}
}
In this example, the event handler calls a findAll() method to return all the
entity beans. You can call any finder you want. You could use the
EntityBeanProvider’s parameterRow property to dynamically determine
which finder to call and/or which parameters to pass.
For resolving, the EntityBeanResolver can by default determine how to
apply updates and deletes. But it can’t automatically determine how to
create new entity beans because there is no way it can determine which
create() method to call and which parameters to pass to it. So, if you want
to add a row to the data source, you must add the create event yourself
and supply the necessary logic. You can use the Inspector to add the
skeleton create event code to your session bean. You can see an example of
a create event in the ejb.jpx sample project. You can also use the other
events available in EntityBeanResolver to override the default behavior, if
you choose.
Deploy the session and entity beans to the application server. For more
information about deploying your beans, see “Deploying to an application
server” on page 6-5.
public PersonnelDataModule() {
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
try {
sessionBeanConnection.setJndiName("Personnel");
sessionBeanConnection.addCreateSessionBeanListener(new
com.borland.dx.ejb.CreateSessionBeanListener() {
public void creating(CreateSessionBeanEvent e) {
sessionBeanConnection_creating(e);
}
});
personnelDataSet.setSessionBeanConnection(sessionBeanConnection);
personnelDataSet.setMethodName("Personnel");
}
catch (Exception ex) {
}
}
public static PersonnelDataModule getDataModule() {
if (myDM == null) {
myDM = new PersonnelDataModule();
}
return myDM;
}
public com.borland.dx.ejb.SessionBeanConnection getSessionBeanConnection() {
return sessionBeanConnection;
}
public com.borland.dx.ejb.EjbClientDataSet getPersonnelDataSet() {
return personnelDataSet;
}
void sessionBeanConnection_creating(CreateSessionBeanEvent e) {
}
}
Handling relationships
The EntityBeanProvider automatically flattens relationships. For example, if
you have any Employee entity bean that has a getDept() method that returns
a Dept, where Dept is an entity bean remote, a DataSet is created that has all
the fields in the Employee entity bean plus all the fields in the Dept entity
bean (including any hidden columns containing the primary keys of each
of the entity beans). Except for Dept.ejbPrimaryKey, the other Dept fields will
be read-only.
To resolve changes when a one-to-one relationship is involved, you must
add an event listener to the EntityBeanProvider because it can’t dynamically
determine the home of the related entity bean. The sample ejb.jpx project
does not demonstrate handling relationships.
The methods of the SessionBean interface are closely associated with the life
cycle of a session bean. This table explains their purpose:
Method Description
setSessionContext() Sets a session context. The bean’s container calls this
method to associate a session bean instance with its
context. The session context interface provides methods
to access the runtime properties of the context in which a
session runs. Usually a session bean retains its context in a
data field.
ejbRemove() Notifies a session object that it is about to be removed.
The container calls this method whenever it removes a
stateful session bean as a result of the client calling a
remove() method of the remote or home interface.
ejbActivate() Notifies a stateful session object that is has been activated.
ejbPassivate() Notifies a stateful session object that it is about to be
deactivated by the container.
Not only does the Enterprise JavaBean wizard create your enterprise bean
class, it also creates the bean’s home and remote interfaces as it creates the
bean class. This way, you are assured the create() method of the home
interface returns the remote interface while the ejbCreate() method always
returns void.
After you write the business methods in your bean class, you can use the
Bean designer to specify which of those you want defined in the bean’s
remote interface. A client application can access only those methods
defined in the remote interface. Once you specify which methods you
want a client to be able to call, the Bean designer defines the methods in
the remote interface for you.
If you already have a complete enterprise bean class, but don’t have home
and remote interfaces for it, you can use JBuilder’s EJB Interfaces wizard
to create them. The method signatures will comply with EJB 1.1
Stateless beans
The life of a stateless session bean begins when the client calls the create()
method of the session bean’s home interface. The container creates a new
instance of the session bean and returns an object reference to the client.
Stateful beans
The life of a stateful session bean begins when the client calls the create()
method of the session bean’s home interface. The container creates a new
instance of the session bean, initializes it, and returns an object reference
to the client.
During the creation process, the container invokes the setSessionContext()
method of the SessionBean interface and calls the ejbCreate() method of the
session bean implementation. As a bean provider, you can use these
methods to initialize the session bean.
The state of the session bean is now method ready, which means it can
perform nontransaction operations or be included in a transaction for
transaction operations. The bean remains in the method-ready state until
one of three things happens:
• The bean enters a transaction.
• The bean is removed.
• The bean is passivated.
When a client calls the remove() method of the remote or home interface,
the container invokes the corresponding ejbRemove() method on the
session bean object. As a bean provider, you put any application-specific
cleanup code in this method. After ejbRemove() completes, the bean object
is no longer usable. If the client attempts to call a method in the bean
object, the container throws the java.rmi.NoSuchObjectException.
The container can deactivate the session bean instance. Usually this occurs
for resource management reasons such as when a session object is idle for
a while or if the container requires more memory. The container
deactivates the bean by calling the bean’s ejbPassivate() method. When a
bean instance is deactivated, which is called passivation, the container
stores reference information and the state of the session object on disk and
frees the memory allocated to the bean. You can add code to ejbPassivate()
if you have some task you want to execute just before passivation occurs.
The container activates the bean object again by calling the ejbActivate()
method. This occurs when the client calls a method on the session bean
that is passivated. During activation, the container recreates the session
object in memory and restores its state. If you want something to happen
immediately after the bean becomes active again, add your code to the
ejbActivate() method.
the wizard declares the three methods with empty bodies in your bean
class:
Method Description
afterBegin() Notifies the bean instance that it is about to be used in a
transaction. Any code you write within afterBegin()
occurs within the scope of the transaction.
beforeCompletion() Notifies the bean instance that the transaction is about to
commit. If the bean has any cached values, use
beforeCompletion() to write them to the database. If
necessary, a session bean could use the beforeCompletion()
method to force the transaction to roll back by calling the
setRollbackOnly() method of the SessionContext interface.
afterCompletion() Notifies the bean instance that the transaction has
completed. If the transaction was committed, the
parameter completionStatus is set to true. If the transaction
was rolled back, the parameter is set to false.
This is how the SessionSynchronization methods are used: The client calls a
transactional business method defined in the remote interface, which puts
the bean object in the transaction-ready state. The container calls the
afterBegin() method in the bean object. Later, if the transaction is
committed, the container calls beforeCompletion(), and then, if the commit
was successful, the afterCompletion(true) method. If the transaction was
rolled back or otherwise failed to commit, the container calls
afterCompletion(false). The session bean object is now in method-ready
state again.
For more information about using session beans in transactions, see
Chapter 13, “Managing transactions.”
The container calls the ejbRemove() method just prior to removing the bean
instance. You can add some application-specific code that would execute
before the bean is removed, but it isn’t required. The CartBean example
leaves the body of the ejbRemove() method empty.
The getTotalPrice() method initializes the total price to zero, then loops
through the item list, adding the price of each element to the total price. It
returns the total price rounded to the nearest penny.
public float getTotalPrice() {
System.out.println("\tgetTotalPrice(): " + this);
float totalPrice = 0f;
Enumeration elements = _items.elements();
while(elements.hasMoreElements()) {
Item current = (Item) elements.nextElement();
totalPrice += current.getPrice();
}
// round to the nearest lower penny
return (long) (totalPrice * 100) / 100f;
}
All data types passed between a client and a server must be serializable.
That is, they must implement the java.io.Serializable interface. In the Cart
example, the bean returns a list of items to the client. If there were no
serializable restrictions, you could use _items.elements() to return the
contents of the item vector. But _items.elements() returns a Java Enumeration
object, which is not serializable. To avoid this problem, the program
implements a class called com.inprise.ejb.util.VectorEnumeration(_items).
This class takes a vector and returns an actual enumeration, which is
serializable, for the contents of that vector. The CartBean object passes this
serializable vector to the client, and receives a serializable vector passed
from the client side. The getContents() method does the conversion
between a Java Enumeration and a serializable VectorEnumeration.
public java.util.Enumeration getContents() {
System.out.println("\tgetContents(): " + this);
return new com.inprise.ejb.util.VectorEnumeration(_items);
}
The purchase() method should do the following:
1 Get the current time.
2 Compare the expiration date of the credit card with the current time. If
the expiration date is prior to the current time, the method throws the
CardExpiredException application exception.
3 Complete the purchasing process, including updating inventory,
posting the charge to the credit card company, and initiating shipment
of the item. (None of this has actually been implemented in the Cart
example.) If an error occurs at any point, the purchase process does not
complete and the method throws a PurchaseProblemException exception.
public void purchase() throws PurchaseProblemException {
System.out.println("\tpurchase(): " + this);
// make sure the credit card has not expired
Date today = Calendar.getInstance().getTime();
if(_expirationDate.before(today)) {
throw new CardExpiredException("Expiration date: " + _expirationDate);
}
// complete purchasing process
// throw PurchaseProblemException if an error occurs
}
CartBean includes a toString() method to print out the CartBean and the
name of the card holder.
// method to print out CartBean and the name of card holder
public String toString() {
return "CartBean[name=" + _cardHolderName + "]";
}
Item class
The CartBean example uses an Item class. Item is public and it extends
java.io.Serializable; serialized data can be passed on the wire:
package shoppingcart;
public class Item implements java.io.Serializable {
private String _title;
private float _price;
public Item(String title, float price) {
_title = title;
_price = price;
}
public String getTitle() {
return _title;
}
public float getPrice() {
return _price;
}
}
Exceptions
There are three exception classes in the Cart example. All are extensions of
the Java class Exception:
public class ItemNotFoundException extends Exception {
public ItemNotFoundException(String message) {
super(message);
}
}
public class PurchaseProblemException extends Exception {
public PurchaseProblemException(String message) {
super(message);
}
}
public class CardExpiredException extends Exception {
public CardExpiredException(String message) {
super(message);
}
}
Required interfaces
Enterprise beans always have two interfaces: a home and a remote
interface. In this example the Cart session bean has a public EJB remote
interface called Cart, and a home interface called CartHome.
When you use the Enterprise JavaBean wizard, the home and remote
interfaces are created at the same time the bean class is. If you already
have a session bean, but not the interfaces, use the EJB Interfaces wizard.
To use the wizard, display the source code of the your enterprise bean in
the code editor and choose Wizards|EJB Interfaces. Respond to the
wizard’s prompts and when you are done, the wizard creates a home and
a remote interface for your enterprise bean.
For more information about using the Enterprise JavaBean wizard and the
EJB Interfaces wizard, see Chapter 3, “Developing enterprise beans.”
The create() method follows the rules defined in the EJB specification: it
throws an RMI remote exception, java.rmi.RemoteException, and it throws
an EJB create exception, javax.ejb.CreateException. The signature of the
create() method matches that of the ejbCreate() method in the session
bean class it terms of the number and type of parameters. The return value
of create() is a Cart remote interface. This is because the CartHome interface
functions as a factory for CartBean. (The return value for the matching
ejbCreate() method in the CartBean class is void.)
<container-transaction>
<method>
<ejb-name>cart</ejb-name>
<method-name>purchase</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
The CartClient program is the client application that uses the Cart
enterprise bean. Its main() routine includes elements that all enterprise
bean client application must implement. It demonstrates how to
• Use JNDI to locate the bean’s home interface.
• Use the home interface’s create() method to create a new remote Cart
object.
• Invoke method declared in the Cart object.
public static void main(String] args) throws Exception {
// get a JNDI context using the Naming service
javax.naming.Context context = new javax.naming.InitialContext();
Object objref = context.lookup("cart");
CartHome home = (CartHome)javax.rmi.PortableRemoteObject.narrow(objref, CartHome.class);
Cart cart;
{
String cardHolderName = "Jack B. Quick";
String creditCardNumber = "1234-5678-9012-3456";
Date expirationDate = new GregorianCalendar(2001, Calendar.JULY,1).getTime();
cart = home home.create(cardHolderName, creditCardNumber, expirationDate);
}
Book knuthBook = new Book("The Art of Computer Programming", 49.95f);
cart.addItem(knuthBook);
... // create compact disc and add it to cart, then list cart contents
summarize(cart)
cart.removeItem(knuthBook);
... // add a different book and summarize cart contents
try {
cart.purchase();
}
catch(PurchaseProblemException e) {
System.out.println("Could not purchase the items:\n\t" + e);
}
cart.remove();
}
The main() routine begins by a JNDI context to look up objects. It
constructs an initial context (a Java naming context). This is standard JNDI
code.
main() looks up the CartHome object called cart. Looking up a name with
JNDI invoking a call from the client to the CosNaming service to look up
the name in CosNaming. The CosNaming service returns an object
reference to the client. In this example, it returns a CORBA object
reference. The program must perform a PortableRemoteObject.narrow()
operation on the object reference and cast the returned object to the type
CartHome, and assign it to the variable home. This call is typical for
Bean-managed persistence
An entity bean with bean-managed persistence contains the code to access
and update a database. That is, you, as the bean provider, write database
access calls directly in the entity bean or its associated classes. Usually you
write these calls using JDBC.
The database access calls can appear in the entity bean’s business
methods, or in one of the entity bean interface methods. (You’ll read more
about the entity bean interface soon.)
Usually a bean with bean-managed persistence is more difficult to write
because you must write the additional data-access code. And, because you
might choose to embed the data-access code in the bean’s methods, it can
also be more difficult to adapt the entity bean to different databases or to a
different schema.
Container-managed persistence
You don’t have to write code that accesses and updates databases for
entity beans with container-managed persistence. Instead, the bean relies
on the container to access and update the database.
Container-managed persistence has many advantages compared to bean-
managed persistence:
• Such beans are easier to code.
• Persistence details can be changed without modifying and recompiling
the entity bean. Instead the deployer or application assembler can
modify the deployment descriptor.
• The complexity of the code is reduced, as is the possibility of errors.
• You, as the bean provider, can focus on the business logic of the bean
and not on the underlying system issues.
Container-managed persistence has some limitations, however. For
example, the container might load the entire state of the entity object into
the bean instance’s fields before it calls the ejbLoad() method. This could
lead to performance problems if the bean has many fields.
ejbCreate() method
If you choose to add additional ejbCreate() methods that include
parameters, remember these rules:
• Each ejbCreate() must be declared as public.
• For container-managed entity beans, an ejbCreate() method must
return null.
The container has complete responsibility for creating container-
managed entity beans.
• For bean-managed entity beans, an ejbCreate() method must return an
instance of the primary key class for the new entity object.
The container uses this primary key to create the actual entity reference.
• The parameters of an ejbCreate() method must be of the same number
and type as those in the corresponding create() method in the bean’s
remote interface.
• Each ejbCreate() method must have a corresponding ejbPostCreate()
method that matches the ejbCreate() in the same number of parameters.
The signature for an ejbCreate() method is the same, regardless whether
the bean uses container-managed or bean-managed persistence. This is
the signature for all ejbCreate() methods of an entity bean:
public <PrimaryKeyClass> ejbCreate( <zero or more parameters> )
// implementation
}
When the client calls the create() method, the container in response
executes the ejbCreate() method and inserts a record representing the
entity object into the database. The ejbCreate() methods usually initialize
some entity state. Therefore, they often have one or more parameters and
their implementations include code that sets the entity state to the
parameter values. For example, the bank example discussed later in this
chapter has a checking account entity bean whose ejbCreate() method
takes two parameters, a string and a float value. The method initializes the
name of the account to the string value and the account balance to the float
value:
public AccountPK ejbCreate(String name, float balance) {
this.name = name;
this.balance = balance;
return null;
}
ejbPostCreate() method
When an ejbCreate() method finishes executing, the container then calls a
matching ejbPostCreate() method to allow the instance to complete its
initialization. The ejbPostCreate() matches the ejbCreate() method in its
parameters, but it returns void:
public void ejbPostCreate( <zero or more parameters> )
// implementation
}
Follow these rules when defining an ejbPostCreate():
• It must be declared as public.
• It can’t be declared as final or static.
• Its return type must be void.
• Its parameter list must match that of the corresponding ejbCreate()
method.
Use ejbPostCreate() to perform any special processing your bean needs to
do before it becomes available to the client. If your bean doesn’t need to
do any special processing, leave the method body empty, but remember to
include one ejbPostCreate() for every ejbCreate() for an entity bean with
bean-managed persistence.
home. There are two ways an entity bean instance moves from the ready
state back to the pooled state:
• The container calls the ejbPassivate() method to disassociate the
instance from its primary key without removing the underlying entity
object.
• The container calls the ejbRemove() method to remove the entity object.
It calls ejbRemove() when the client application calls the bean’s home or
remote remove() method.
To remove an unassociated instance from the pool, the container calls the
instance’s unsetEntityContext() method.
home interface for entity beans must include at least one finder method. A
create() method is optional.
Here is the code for the AccountHome interface:
public interface AccountHome extends javax.ejb.EJBHome {
Account create(String name, float balance)
throws java.rmi.RemoteException, javax.ejb.CreateException;
Account findByPrimaryKey(AccountPK primaryKey)
throws java.rmi.RemoteException, javax.ejb.FinderException;
java.util.Enumeration findAccountsLargerThan(float balance)
throws java.rmi.RemoteException, javax.ejb.FinderException:
}
The AccountHome home interface implements three methods. While the
create() method is not required for entity beans, the bank example does
implement one. The create() method inserts a new entity bean object into
the underlying database. You could choose to defer the creation of new
entity objects to the DBMS or to another application, in which case you
would not define a create() method.
The create() method requires two parameters, an account name string and
a balance amount. The implementation of this method in the entity bean
class uses these two parameter values to initialize the entity object
state—the account name and the starting balance—when it creates a new
object. The throws clause of a create() method must include the
java.rmi.RemoteException and the java.ejb.CreateException. It can also
include additional application-specific exceptions.
Entity beans must have the findByPrimaryKey() method, so the AccountHome
interface declares this method. It takes one parameter, the AccountPK primary
key class, and returns a reference to the Account remote interface. This
method finds one particular account entity and returns a reference to it.
Although it’s not required, the home interface also declares a second finder
method, findAccountsLargerThan(). This method returns a Java Enumeration
containing all the accounts whose balance is greater than some amount.
managed persistence. When you compare the descriptor tags for the two
types of entity beans, you’ll notice that the deployment descriptor for an
entity bean with container-managed persistence is more complex.
The bean’s deployment descriptor type is set to <entity>. Notice that the
first tags within the <enterprise-beans> section in both code samples
specify that the bean is an entity bean.
An entity bean deployment descriptor specifies the following type of
information:
• The names of the related interfaces (home and remote) and the bean
implementation class.
Each enterprise bean specifies its home interface using the <home> tag,
its remote interface using the <remote> tag, and its implementation
class name using the <ejb-class> tag.
• The JNDI names under which the entity bean is registered and by
which clients locate the bean.
• The bean’s transaction attributes and its transaction isolation level.
This usually appears in the <assembly-descriptor> section of the
deployment descriptor.
• The name of the entity bean’s primary key class.
In this example, the primary key class is AccountPK and it appears within
the <prim-key-class> tag.
• The persistence used by the bean.
The CheckingAccount bean uses container-managed persistence, so the
deployment descriptor sets the <persistence-type> tag to Container.
• Whether the bean class is reentrant.
Neither the SavingsAccount nor the CheckingAccount bean is reentrant, so
the <reentrant> tag to set to False for both.
• The fields that the container manages, if the bean uses container-
managed persistence.
A bean that uses bean-managed persistence doesn’t specify any
container-managed fields. Therefore, the deployment descriptor for the
SavingsAccount bean doesn’t specify any container-managed fields. An
entity bean using container-managed persistence must specify the
names of its fields or instance variables that the container must manage.
Use a combination of the <cmp field> and <field name> tags for this.
The first tag, <cmp field>, indicates that the field is container-managed.
Within this tag, the <fields name> tag specifies the name of the field
itself. For example, the CheckingAccount bean deployment descriptor
indicates that the balance field is container-managed as follows:
<cmp field><field name>balance</field name></cmp field>
Information about the container-managed fields for container-managed
beans. The container uses this information to generate the finder methods
for these fields.
these values, the descriptor specifies the fields that the container will
manage.
<enterprise-beans>
<entity>
<description>This entity bean is an example of container-managed persistence
</description>
<ejb-name>checking</ejb-name>
<home>AccountHome></home>
<remote>Account</remote>
<ejb-class>chkingAccount</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>AccountPK>/prim-key-class>
<reentrant>False</reentrant>
<cmp-field>
<field-name>name</field-name>
<cmp-field>
</entity>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>chekcing</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute-transaction>
</container-transaction>
</assembly-descriptor>
The following sample home interface contains two create() methods and
two finder methods. The parts shown in bold are required:
public interface AccountHome extends javax.ejb.EJBHome {
Session beans
If the enterprise bean is a session bean, the client uses a create method to
return the remote interface. Session beans don’t have finder methods. If
the session bean is stateless, it will have just one create() method, so that is
the one the client must call to obtain the remote interface. The default
create() method has no parameters. So for the SortClient code sample, the
call to the get the remote interface looks like this:
Sort sort = home.create();
The cart example discussed in Chapter 9, “Developing session beans,” on
the other hand, uses a stateful session bean, and its home interface,
CartHome, implements more than one create() method. One of its create()
methods takes three parameters, which together identify the purchaser of
the cart contents, and returns a reference to the Cart remote interface. The
CartClient sets values for the three parameters—cardHolderName,
creditCardNumber, and expirationDate—then calls the create() method.
Here’s the code:
Cart cart;
{
String cardHolderName = "Jack B. Quick";
String creditCardNumber = "1234-5678-9012-3456";
Date expirationDate = new GregorianCalendar(2001, Calendar.JULY, 1).getTime();
cart = home.create(cardHolderName, creditCardNumber, expirationDate);
}
Entity beans
If it’s an entity bean, use either a create or a finder method to obtain the
remote interface. Because an entity object represents some underlying
data stored in a database, and that data is persistent, entity beans usually
exist for a long time. Therefore, the client most often needs to simply find
the entity bean that represents that data rather than create a new entity
object, which would create and store new data in the underlying database.
A client uses a find operation to locate an existing entity object, such as a
specific row within a relational database table. That is, find operations
locate data entities that have previously been inserted into data storage.
The data might have been added to the data store by an entity bean, or it
might have been added outside of the EJB context, such as directly from
within the database management system (DBMS). Or, in the case of legacy
systems, the data might have existed prior to the installation of the EJB
container.
A client uses an entity bean object’s create() method to create a new data
entity that will be stored in the underlying database. An entity bean’s
create() method inserts the entity state into the database, initializing the
entity’s variables according to the values in the create() method’s
parameters.
Each entity bean instance must have a primary key that uniquely
identifies it. An entity bean instance can also have secondary keys that can
be used to locate a particular entity object.
Calling methods
Once the client has a reference to the bean’s remote interface, it can invoke
the methods defined in the remote interface for the bean. The client is
most interested in the methods that embody the bean’s business logic.
For example, the following is some code from a client that accesses the cart
session bean. The code shown here begins from the point where it has created
a new session bean instance for a card holder and retried a Cart reference to
the remote interface. The client is ready to invoke the bean methods:
...
Cart cart;
{
...
// obtain a reference to the bean's remote interface
cart = home.create(cardHolderName, creditCardNumber, expirationDate);
}
A client can also keep a handle to the session for future reference,
however.
Clients of entity beans don’t have this problem as entity beans are
associated with a client only for the duration of a transaction and the
container is in charge of their life cycles, including their activation and
passivation. A client of an entity bean calls the bean’s remove() method
only when the entity object is to be deleted from the underlying database.
Managing transactions
A client program can manage its own transactions rather than letting the
enterprise bean (or container) manage the transactions. A client that
manages its own transactions does so in exactly the same manner as a
session bean that manages its own transactions.
When a client manages its own transactions, it’s responsible for delimiting
the transaction boundaries. That is, it must explicitly start the transaction
and end (commit or roll back) the transaction.
A client uses the javax.transaction.UserTransaction interface to manage its
own transactions. It must first obtain a reference to the UserTransaction
interface, using JNDI to do so. Once it has the UserTransaction context, the
client uses the UserTransaction.begin() method to start the transaction,
followed later by the UserTransaction.commit() method to commit and end
the transaction (or UserTransaction.rollback() to rollback and end the
transaction). In between, the client accesses EJB objects and so on.
The code shown here demonstrates how a client would manage its own
transactions; the code that pertains specifically to client-managed
transactions are highlighted in bold:
...
import javax.naming.InitialContext;
import javax.transaction.UserTransaction;
...
public class clientTransaction {
public static void main (String[] argv) {
InitialContext initContext = new InitialContext();
UserTransaction ut = null;
ut = (UserTransaction)initContext.lookup("java:comp/UserTransaction");
// start a transaction
ut.begin();
• The bean’s remote interface class object, including all class information,
using the EJBMetaData.getRemoteInterfaceClass() method.
• The bean’s primary key class object, using the
EJBMetaData.getPrimaryKeyClass() method.
• Whether the bean is a session bean or an entity bean, using the
EJBMetaData.isSession() method. The method returns true if this is a
session bean.
• Whether a session bean is stateless or stateful, using the
EJBMetaData.isStatelessSession() method. The method returns true if the
session bean is stateless.
Here’s the EJBMetaData interface in its entirety:
package javax.ejb;
13
Managing transactions
Chapter13
Characteristics of transactions
Usually transactions refer to operations that access a database. All access
to the database occurs in the context of a transaction. All transactions
share these characteristics, denoted by the acronym ACID:
• Atomicity
Usually a transaction consists of more than a single operation.
Atomicity requires that all of the operations of a transaction are
performed successfully for the transaction to be considered complete. If
all of a transaction’s operations can’t be performed, that none of them
are allowed to be performed.
• Consistency
Consistency refers to database consistency. A transaction must move
the database from one consistent state to another, and it must preserve
the database’s semantic and physical integrity.
• Isolation
Isolation requires that each transaction appear to be the only
transaction currently manipulating the data in the database. Although
other transactions can run concurrently, a transaction shouldn’t see
these manipulations until and unless they complete successfully and
commit their work. Because of interdependencies among updates, a
transaction might get an inconsistent view of the data were it to see just
a subset of another transaction’s updates. Isolation protects a
transaction from this sort of data inconsistency.
Isolation is related to transaction concurrency. There are levels of
isolation. Higher degrees of isolation limit the extent of concurrency.
The highest level of isolation occurs when all transactions can be
serialized. That is, the database contents appear as if each transaction
ran by itself to completion before the next transaction began. Some
applications, however, might be able to tolerate a reduced level of
isolation for a higher degree of concurrency. Usually these applications
run a greater number of concurrent transactions, even it transactions
are reading data that might be partially updated and possibly
inconsistent.
• Durability
Durability means that updates made by committed transactions persist
in the database regardless of failure conditions. Durability guarantees
that committed updates remain in the database despite failures that
occur after the commit operation, and that the databases can be
recovered after a system or media failure.
operation calls the transaction starting method, but no operation calls the
transaction ending method.
Whenever possible, you should write enterprise beans that use container-
managed transactions. They require less work on your part and are less
prone to errors. Also, it’s easier to customize a bean with a container-
managed transaction and to use it to compose other beans.
Transaction attributes
Enterprise beans that use container-managed transaction have transaction
attributes associated with each method of the bean or with the bean as a
whole. The attribute value tells the container how it must manage the
transactions that involve the bean. There are six different transaction
attributes that the application assembler or deployer can associate with
each method of a bean:
• Required
Guarantees that the work performed by the associated method is
within a global transaction context. If the caller already has a
transaction context, the container uses the same context. If the caller
doesn’t have a transaction context, the container begins a new
transaction automatically. Using this attribute makes it easy to compose
multiple beans and coordinate the work of all the beans using the same
global transaction.
• RequiresNew
Used when you don’t want the method associated with an existing
transaction. It ensures that the container always begins a new
transaction.
• Supports
Permits the method to avoid using a global transaction. Use this
attribute only when a bean’s method accesses just one transaction
resource or no transaction resources, and the method doesn’t invoke
another enterprise bean. Because this attribute avoids the cost
associated with global transactions, using it optimizes your bean. If this
attribute is set and a global transaction already exists, the container
invokes the method and it joins the existing global transaction. If there
is no global transaction, the container starts a local transaction for the
method and the transaction completes at the end of the method.
• NotSupported
Also permits the bean to avoid using a global transaction. If a client
calls the method with a transaction context, the container suspends it.
At the end of the method, the global transaction resumes.
• Mandatory
The client that calls a method with this transaction attribute must
already have an associated transaction. If it doesn’t, the container
throws a javax.transaction.TransactionRequiredException. Using this
attribute makes the bean less flexible for composition because it makes
assumptions about the caller’s transaction.
• Never
The client that calls a method with this transaction attribute must not
have a transaction context. If it does, the container throws an exception.
dataSource1 = (javax.sql.DataSource)
context.lookup("java:comp/env/jdbcDatabase1");
firstConnection = dataSource1.getConnection();
firstStatement = firstConnection.createStatement();
dataSource2 = (javax.sql.DataSource)
context.lookup("java:comp/env/jdbcDatabase2");
secondConnection = dataSource2.getConnection();
secondStatement = secondConnection.createStatement();
utx = ejbContext.getUserTransaction();
utx.begin();
firstStatement.executeQuery(...);
firstStatement.executeUpdate(...);
secondStatement.executeQuery(...);
secondStatement.executeUpdate(...);
utx.commit();
firstStatement.close;
secondStatement.close
firstConnection.close();
secondConnection.close();
}
...
System-level exceptions
An enterprise bean throws a system-level exception (usually a
java.ejb.EJBException, but possibly a java.rmi.RemoteException) to indicate
an unexpected system-level failure. For example, it throws an exception if
it can’t open a database connection. The java.ejb.EJBException is a runtime
exception and it isn’t required to be listed in the throws clause of the bean’s
business methods.
System-level exceptions usually require the transaction to be rolled back.
Often the container managing the bean does the rollback. Sometimes the
client must roll back the transaction, though, especially if transactions are
bean-managed.
Application-level exceptions
The bean throws an application-level exception to indicate application-
specific error conditions. These are business logic errors, not system
problems. Application-level exceptions are exceptions other than
java.ejb.EJBException. Application-level exceptions are checked
exceptions, which means you must check for them when you call a
method that potentially can throw this exception.
The bean’s business methods use application exceptions to report
abnormal application conditions, such as unacceptable input values or
amounts beyond acceptable limits. For example, a bean method that
debits an account balance might throw an application exception to report
that the account balance isn’t sufficient to permit a particular debit
operation. A client can often recover from these application-level errors
without having to roll back the entire transaction.
The application or calling program gets back the same exception that was
thrown, allowing the calling program to know the precise nature of the
problem. When an application-level exception occurs, the enterprise bean
instance doesn’t automatically roll back the client’s transaction. The client
now has the knowledge and the opportunity to evaluate the error
message, take the necessary steps to correct the situation, and recover the
transaction. Or the client can abort the transaction.
You, as the bean provider, must ensure that the state of the bean is such
that if the client continues with the transaction, there is no loss of data
integrity. If you can’t ensure this, you must mark the transaction for
rollback.
Transaction rollback
When your client gets an application exception, first check if the current
transaction has been marked for rollback only. For example, a client might
receive a javax.transaction.TransactionRolledbackException. This exception
indicates that the helper enterprise bean failed and the transaction has
been aborted or marked “rollback only”. Usually the client doesn’t know
the transaction context within which the enterprise bean operated. The
bean might have operated in its own transaction context separate from the
calling program’s transaction context, or it might have operated in the
calling program’s context.
If the enterprise bean operated in the same transaction context as the
calling program, then the bean itself (or its container) has already marked
the transaction for rollback. When an EJB container marks a transaction
for rollback, the client should stop all work on the transaction. Usually a
client using declarative transactions gets an appropriate exception, such as
javax.transaction.TransactionRolledbackException. Note that declarative
transactions are those transactions where the container manages the
transaction details.
A client that is itself an enterprise bean should call the
javax.ejbEJBContext.getRollbackOnly() method to determine if its own
transaction has been marked for rollback.
For bean-managed transactions—those transactions managed explicitly
by the client—the client should roll back the transaction by calling the
rollback() method from the java.transaction.userTransaction interface.
Index I-1
deactivating transaction policies 7-19
session bean instances 9-7 verifying 7-27
deleting viewing 7-2
EJB instances 11-2 XML file 3-18
enterprise beans 11-7 deployment EJB role 1-4
Deploy Settings dialog box 6-1 deployment options
deployed EJB JARS EJB 6-9
listing 6-9 design patterns
deployer Session Bean wrap Entity Bean 8-1
EJB role 1-4 developer support 1-8
deploying distributed applications
EJB JAR to running container 6-9 EJB 1-1
EJB JARs 6-5 documentation conventions 1-10
enterprise beans 6-1, 6-5 platform conventions 1-11
enterprise beans to WebLogic 6-1, 6-8
enterprise beans to WebSphere 6-1, 6-8 E
Deployment Descriptor editor 7-1
Data Source panel 7-20 editing deployment descriptors 7-1
data source properties 7-22 EJB 1-1
displaying 7-2 See also Enterprise JavaBeans
EJB References panel 7-8 EJB 1.1 application server 2-4
Environment panel 7-6 EJB Bean Generator wizard 3-11
Finders panel 7-13 EJB client components 8-2
Main panel 7-4 EJB components 8-1
method permissions 7-25 EJB container
Persistence panel 7-11 activating session beans 9-7
Properties panel 7-14 container-managed persistence 10-2
Resource References panel 7-10 creates EJBObject 11-7
Security Role References panel 7-9 deactivating session beans 9-7
security roles 7-24 defined 1-5
transaction isolation levels 7-22 implements home interface 11-1
verifying descriptors 7-27 life cycle of entity bean 10-8
deployment descriptors life cycle of stateful beans 9-6
adding information for new bean 7-4 life cycle of stateless beans 9-5
application assembly information 6-4 provider 1-3
changing bean information 7-4 transaction support 13-2
creating 6-2, 7-1 EJB deployment options
data source properties 7-22 setting 6-9
data sources 7-20 EJB Deployment wizard 6-5
editing 3-18, 7-1 EJB Entity Bean Modeler wizard 4-1
EJB references 7-8 EJB Group From Descriptors wizard 3-3
entity bean sample 10-20 EJB groups
environment properties 7-6 build properties 3-16
finder methods 7-13 copy deployment descriptors from 3-16
information in 6-3 creating 3-2
inserting into EJB group 3-16 defined 3-1, 3-2
method permissions 7-25 empty 3-2
persistence 7-11 file extensions 3-1
properties 7-14 from deployment descriptors 3-3
purpose 6-2 inserting deployment descriptors into 3-16
resource references 7-10 types 3-1
security roles 7-9, 7-24 EJB Interface Generator wizard 3-13
session bean 9-17 EJB roles 1-2
structural information 6-3 EJB server
transaction isolation levels 7-22 defined 1-5
provider 1-3
Index I-3
F session bean sample 11-3
session beans 11-2
findByPrimaryKey() 11-5, 12-4 hot deploying
finder methods 7-13, 10-5, 11-5, 12-2, 12-3 enterprise beans 6-9
creating 10-6
default 12-4 I
entity beans 10-3
prefix 11-5 iaspt.ini file 7-28
requirements 10-7 ignoreColumnsOnInsert property 7-14
FinderException exception 11-5 infrastructure EJB roles 1-3
finding entity objects initial naming context
primary key 11-7 obtaining 12-2
fonts InitialContext 13-6
JBuilder documentation conventions 1-10 interfaces
home 11-1
G remote 11-6
isIdentical()
Generate IIOP option 3-16 EJBObject 11-7
getEJBHome() isolation levels 7-22
EJBObject 11-7
getEJBMetaData() 11-2 J
EJBHome 11-2
getHandle() Java Transaction API (JTA) 13-6
EJBObject 11-7 jdbcAccesserFactory property 7-14
getHomeHandle() JNDI
EJBHome 11-2 API 12-2
getMetaData() naming service 12-2, 13-6
enterprise bean 12-8
getPrimaryKey() L
EJBObject 11-7
libraries
getPrimaryKeyAfterInsertSql property 7-14
application server files 2-3
getPrimaryKeyBeforeInsertSql property 7-14
listing deployed JARS 6-9
getRollbackOnly() 13-9
locating
enterprise beans with primary key 11-7
H lookup() 12-2
handles
EJB 11-2 M
getting enterprise 11-7
Mandatory transaction attribute 13-4
home and remote interfaces
metadata
entity beans sharing 10-10
defined 12-8
home interface
method permissions 6-5, 7-25
client locates 12-1, 12-2
method-ready state
create methods 12-2, 12-4
defined 9-6
creating 11-1, 11-2
in transaction 9-7
creating for existing enterprise bean 3-13
multi-tier applications
defined 11-1
for distributed systems 1-1
entity bean requirements 11-4
entity bean sample 11-6
entity beans 10-10, 11-4 N
extends EJBHome 11-2 naming context
finder methods 11-5, 12-2 obtaining 12-2
naming 11-1 Never transaction attribute 13-4
remove methods 12-4 newsgroups 1-9
session bean requirements 11-3 Borland 1-9
Index I-5
security role references 6-5
security roles 6-4
T
creating 7-24 target application server 2-1
EJB 7-9, 7-24 technical support 1-8
server provider test clients
EJB 1-3 creating EJB 5-1
EJB role 1-3 declaring instance of 5-3
servers running EJB 5-5
EJB 1-5 using EJB 5-3
running EJB 5-5 testing enterprise bean methods 5-1
session bean classes testing enterprise beans 5-5
requirements 9-2 transaction
Session Bean wrap Entity Bean design pattern 8-1 attributes 13-4
session beans 1-7, 9-1 boundaries 12-7, 13-6
Cart sample 9-10 demarcation 13-3
create methods 12-2 policies 7-19
create() 11-3 transaction-ready state 9-8
creating with JBuilder 9-4 transactions
home interface 11-2 and enterprise beans 13-3
implementing required methods 9-11 atomicity characteristic 13-1
life cycle 9-5 attributes 13-3
method-ready state 9-6 bean-managed 13-3
referencing 12-2 characteristics 13-1
remove() 12-5 concurrency characteristic 13-1
sample 9-9 consistency 13-1
SessionSyncronization interface 9-7 container-managed 7-19, 13-3, 13-5
stateful 9-1, 12-2 demarcation 13-6
stateless 9-2, 12-2 durability characteristic 13-1
stateless pool 9-5 exceptions 13-7
types 9-1 global 13-5
writing 9-2 isolation characteristic 13-1
SessionBean interface isolation levels 7-22
extending 9-2 local 13-5
methods 9-2 managed by client 12-7
SessionContext interface 9-8 rolling back 13-9
SessionSynchronization interface
methods 9-8 U
stateful session beans 9-7
setEntityContext() 10-4 undeploying an EJB JAR 6-9
setRollbackOnly() 9-8 unsetEntityContext() 10-4
setSessionContext() 9-3 Use EJB Test Client wizard 5-3
sharing home and remote interfaces 10-10 Usenet newsgroups 1-9
shopping cart UserTransaction interface 12-7, 13-5, 13-6
session bean sample 9-9
SmartAgent 2-3 V
stateful beans verifying
life cycle 9-6 deployment descriptors 7-27
stateless beans VisiBroker
life cycle 9-5 ORB, making available to JBuilder 2-3
stubs SmartAgent 2-3
generating client 3-16
Supports transaction attribute 13-4
system administrator
EJB role 1-4
Index I-7