Transcript Lecture 8
Lecture 8
Advanced Topics in
Enterprise JavaBeans
Primary Container-Bean Callbacks
• ejbCreate()
– called by the container after a client has invoked one of
the create methods on the bean’s home interface. There
should be a one-one match between the create methods
in the bean’s home interface and the ejbCreate()
methods in the bean’s implementation. Realized by the
bean’s implementation.
• ejbRemove()
– called by the container just before the bean is
destroyed, after which, the bean is available for garbage
collection by the JVM.
Primary Container-Bean Callbacks
• ejbActivate()
– called by the container during deserialization out of
passivated state. This is the bean’s opportunity to
restore handles to any resources it needs to function.
Realized by the bean’s implementation.
• ejbPassivate()
– called by the container during serialization into a
passivated state. A passivated state is where the
conversational state of the bean is stored in some semipermanent storage for possible later recovery. This
method allows the bean to release any handles to
resurces that it currently has open. Realized by the
bean’s implementation.
Introduction to Entity Beans
• Entity Beans provide an encapsulation of business
entities in the problem domain
• Entity Beans persist across multiple client
communications and over the lifetime of the EJB
server.
• Entity Beans always represent the current state
(dependent on the Isolation Level) of the business
data.
• When the entity bean is no longer needed, the
container will call ejbPassivate before releasing
the entity bean.
Introduction to Entity Beans
• Entity Beans which have been passivated are
returned to the container’s pool of entity beans for
possible later reuse.
• Entity Beans must provide a class encapsulation of
the primary key which serves as the index into the
database.
• Entity Beans are defined to run within connection
pools, which are described in the Bean’s metadata
(deployment descriptor).
The Primary Key
• The primary key contains all the information necessary to uniquely
associate a business object at runtime with it’s data in permanent
storage.
• Often, the primary key will be some ID number, or combination of
fields which will uniquely identify a particular business object in
storage.
• The container will use the primary key during it’s load and save
mechanisms.
• A primary key must implement the Serializable interface.
• A primary key is usually a very simple class that defines one or more
data members that collectively uniquely identify a business object,
along with at least two constructors (one of which takes the arguments
for setting the data members).
• The primary key fields must be a subset of the container-managed
fields defined in the deployment descriptor
The Primary Key
• Primary keys must:
– be a public class
– offer a default constructor (no args)
– be a class containing all public data members (no
private data members)
– be a class whose data member names exactly match the
corresponding data members of the entity bean’s
implementation
– be declared in the Deployment Descriptor for the bean
• All BMP Bean implementations must define an
ejbFindByPrimaryKey(PK) method.
Entity Bean Persistence, Revisited
Bean-Managed Persistence (BMP)
Bean developer, not the container, provides all data access
logic
Developer implements callbacks such as ejbFind…(),
ejbCreate(), ejbActivate(), ejbLoad(), ejbStore(),
ejbPassivate(), ejbRemove()
Developer uses JDBC or SQL/J to interact with the
database
Entity Bean Persistence, Revisited
Container-Managed Persistence (CMP)
The container explicitly defines and implicitly performs all database
operations on behalf of the CMP entity bean
You must provide a serializable Primary Key class
Object-Relational database mapping is done declaratively in the
deployment descriptor via EJB Query Language (EJB QL)
Programmer generally writes little if any direct JDBC connection
code (but is free to if he wishes)
finder functions are described in the deployment descriptor:
EJB Query Language
<query>
<query-method>
<method-name>findByName</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>
<![CDATA[SELECT OBJECT(a) FROM MyBean AS a WHERE
name = ?1]]>
</ejb-ql>
NOTE: All Finder methods are declared in Java in the
HOME interface.
Subordinate Entity Bean Callbacks
• The ejbCreate() methods actually create storage in the
database
– for BMP, usually through an “insert into …” SQL
statement
– for CMP, just sets the bean’s state via the bean’s
member variables
• The ejbRemove() method actually destroys storage in the
database
– for BMP, usually through a “delete from …” SQL
statement
– for CMP, usually has an empty body
• A matching ejbPostCreate() method must exist for each
ejbCreate() method defined in the Bean’s implementation
(and thus for each create() in the Home Interface).
Subordinate Entity Bean Callbacks
• The ejbStore() method is called when the bean
needs to store its state to permanent storage
• The ejbLoad() method is called when the bean
needs to load its state from permanent storage
– loading takes place on the basis of the primary
key which is derived from the bean’s current
context
• The setEntityContext(EntityContext) method is
called in order to pass the bean a runtime context
• The unsetEntityContext() method is called to
allow the bean’s implementation to release its
association with a particular context
The Entity Context
• The bean’s current state is controlled by an
EntityContext object
– set via the setEntityContext(EntityContext)
callback
– unset via the unsetEntityContext() callback
• Think of an Entity Bean object as a modular shell
(or skeleton) which can have different EJBObjects
(implementations) and primary keys “plugged in”
during the runtime of the application
The Entity Context
• the bean’s corresponding EJBObject via the
getEJBObject() method
• the bean’s corresponding primary key via the
getPrimaryKey() method
• other default context methods:
– getHome() - get a reference to the Home object factory
– getEnvironment() - gets user-defined environment
properties (in DD)
– java.security.Identity getCallerIdentity()
– isCallerInRole(java.security.Identity)
– getUserTransaction() - for TX_BEAN_MANAGED
transactions
– setRollbackOnly() - mark rollback flag in current
transaction
– getRollbackOnly - find out if marked for rollback
Finder Methods
• Finder methods offer clients a way to retrieve entity beans that
already exist (as opposed to calling create(…) methods)
• Finder methods are declared in the entity bean’s home interface and:
– For BMP: implemented in the bean’s implementation
– For CMP: prototyped in the deployment descriptor for the bean.
• All findXXX() methods declared in the home interface must either:
– return a reference to the Remote Object; or
– return a collection of references to the Remote Object
• EJB 1.0: only Enumeration types allowed
• EJB 1.1: both Enumeration and new Java 2 Collection classes
allowed
• EJB 2.0: use Collection classes with Iterators
• Clients use finder methods to locate existing data entities in the
persistent store
The Entity Bean Life Cycle
• NonExistant
– moves to Pooled state via a Class.newInstance() call by the
container, followed by setEntityContext()
• Pooled
– moves to Ready state via a client-provoked create() or
findXXX(), and a container called ejbCreate() and
ejbPostCreate()
– moves to NonExistent state via a container called
unsetEntityContext() call or a JVM-provoked Object.finalize()
call
• Ready
– allows ejbStore() and ejbLoad() methods to be called by the
container
– moves to Pooled state via a client-provoked remove() call (thus
ejbRemove()) or a container-provoked ejbPassivate() call
Entity Bean Life Cycle:
Object Creation
• When the server starts, a connection pool (defined in the
Deployment Descriptor) is created, and one or more entity
beans is instantiated to handle incoming client requests.
• A client calls a create(…) method or a findXXX(…)
method on an entity bean’s home interface
– When create() is called, the container chooses a bean
from the pool and calls the corresponding ejbCreate(…)
method on the bean’s remote interface. This method
creates a primary key object within the container.
– When a findXXX() method is called, the container
chooses a bean from the pool and calls its
corresponding ejbFindXXX() method (which may be
defined in the bean’s implementation for BMP or is
provided by the container in CMP). This method
creates one or more primary key objects within the
container.
Entity Bean Life Cycle:
Object Creation
• The container then assigns an identity (via
the primary key and an associated remote
EJBObject) to a new EntityContext, and
hands this EntityContext off to an existing
entity bean skeleton by calling its
setEntityContext() method
• The entity bean’s implementation of
setEntityContext() then stores this context
in a member variable (non-persistent).
Entity Bean Life Cycle:
Object Passivation/Activation
• If all references to the entity bean have been
dissolved, or if the container needs an available
entity bean skeleton, the container may passivate
an entity bean
• The container calls ejbStore() (for BMP beans) to
allow the bean to store its internal state into
persistent storage.
• The container then calls ejbPassivate() on the
entity bean, which allows the bean to free any
connections or handles it may be currently
holding.
Entity Bean Life Cycle:
Object Passivation/Activation
• After passivation, the bean reenters the connection pool of
available beans and is available for reassignment
• All beans in the pool are equivalent, they all have an
EntityContext, but that context is not associated with a
particular business entity (it’s primary key and EJBObject
are null).
• During activation, a bean is pulled from the bean pool, its
EntityContext is reassociated with a particular business
entity by reassignment of its primary key and EJBObject,
and then ejbActivate() is called, followed by ejbLoad()
which in the case of CMP beans notifies the bean that it
has data or in the case of BMP allows the bean to reload its
data.
EJB Development
•
•
•
•
•
•
•
Create the Remote Interface
Create the Home Interface
Create the Bean Implementation
Create the Deployment Descriptor text file
Run ejbc on the serialized deployment descriptor
Create a manifest file (optional)
Jar the bean files
Jar File Contents
•
•
The jar file, after creation, should contain, at a minimum, the following files:
The class for the Remote Interface
The class for the Bean Implementation
The class for the Home Interface
The serialized deployment descriptor for your Bean implementation
The Enterprise Object Implementation for your bean
The Service Stub for the Enterprise Object Implementation
The WebLogic Skeleton for the Enterprise Object Implementation
The WebLogic Stub for the Enterprise Object Implementation
A Service Stub for your Bean Implementation
A WebLogic Skeleton for your Bean Implementation
A WebLogic Stub for your Bean implementation
Serialized descriptors for the Enterprise Object Implementation
Deployment Descriptor Contents:
ejb-jar.xml
•
•
•
•
•
<ejb-name>: JNDI name of bean for lookup
<ejb-class>: The name of the EJB class
<home>: the name of the Home interface class
<remote>: the name of the Remote interface class
<reentrant>: [true|false]: if true, the same
transaction is allowed to revisit a bean
• <prim-key-class>: the type (class) of the primary
key
• <persistence-type>: the type of persistence desired
(container/bean)
Deployment Descriptor Contents:
Control Descriptors
• Setting Transaction capabilities:
• <trans-attribute>Required</trans-attribute> in ejb-jar.xml
– Never:
Never involved in a transaction.
– Mandatory:
Caller must start transaction.
– Required:
EJBean requires a ransaction
– NotSupported: Container suspends caller's transaction
– RequiresNew: Container starts a new transaction for
every call
– Supports:
Container simply passes the caller's
transaction along.
Deployment Descriptor Contents:
Environment Properties
• <max-beans-in-free-pool>: decides the size of the pool
• <max-beans-in-cache>: Maximum number of objects of
this class that are allowed in memory
• <idle-timeout-seconds>: the LRU chain is cleaned of
inactive objects at this interval in seconds
• <is-modified-method-name>: A flag for the name of the
method called when the entity bean is stored. Returns true
or false if the bean has been modified.
Deployment Descriptor Contents:
Finder Descriptors
• For CMP beans only
• “findXXXName” “description”
– where:
• operator can be one of:
"(", ")", "=", "<", ">", "<=", ">=",
"!", "&", "|", “LIKE", “IS NULL", “IS EMPTY”
• argument parameters are referenced with ?, as in
‘?1’, ‘?2’, etc.
• think of the expression as a SQL “where” clause in
select statement
Deployment Descriptor Contents:
Finder Descriptors
•
Example findByName(String name):
– Old way: “findByName(String name)” “(= name $name)”
– New way:
<query>
<query-method>
<method-name>findAccount</method-name>
<method-params>
<method-param>double</method-param>
</method-params>
</query-method>
<ejb-ql>
<![CDATA[SELECT OBJECT(a) FROM AccountBean AS a
WHERE a.balance = ?1]]>
</ejb-ql>
</query>
Example EJB QL Calls
• Find all items with status between 10 and 20:
– SELECT OBJECT(p) FROM Items p WHERE p.status
BETWEEN 10 AND 20
• Find all items with bidAmount greater than a parameter
passed in:
– SELECT OBJECT(p) FROM Items p WHERE p.bidAmount > ?1
• Find all users whose name begins with an ‘S’:
– SELECT u.name FROM Users u WHERE u.name LIKE ‘S%’
• Find all auctions:
– SELECT a.id FROM Auctions a
weblogic-cmp-rdbms-jar.xml:
Class Attribute – Database Column Mapping
Maps class attributes to database columns:
<weblogic-rdbms-jar>
<weblogic-rdbms-bean>
<ejb-name>containerManaged</ejb-name>
<data-source-name>examples-dataSource-demoPool</data-sourcename>
<table-name>ejbAccounts</table-name>
<field-map>
<cmp-field>accountId</cmp-field>
<dbms-column>id</dbms-column>
</field-map>
…
</weblogic-rdbms-bean>
<create-default-dbms-tables>True</create-default-dbms-tables>
</weblogic-rdbms-jar>