CIS 386 Course Advanced Enterprise Java Programming
Enterprise JavaBeans: BMP and CMP Entity Beans
René Doursat Guest Lecturer Golden Gate University, San Francisco February 2003
EJB Trail • Session Beans – Stateless – Stateful • Entity Beans – Bean-Managed Persistence (BMP) – Container-Managed Persistence (CMP) • Message-Driven Beans
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
2
Algorithmic Computation: No External Data
(a, b, c)
Calculator Session Bean
Client log(a + b)/c2
• one-shot request • stateless
E2-E4 F7-F5
Client
...
checkmate
2/2003
Chess Player Session Bean • conversation • stateful (= chessboard)
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
3
Business Computation: Manages External Data
John Doe?
411 Session Bean
Client
Phone Book
555 1212
• one-shot request • stateless
login ok
Client
add item
Shopping Session Bean
... checkout
2/2003
Inventory, Customers, Shopping Carts
• conversation • stateful (= session ID)
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
4
Simple Session: Direct Data Access Possible
John Doe? SELECT phone WHERE name=‘John Doe’
411 Session Bean
Client
Phone Book
555 1212
• one-shot request • stateless
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
5
Complex Session: How To Access Data?
??
login ok
Client
add item
Shopping Session Bean
...
Inventory, Customers, Shopping Carts
checkout
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
6
Complex Session: Direct Data Access Not Advised
Add-Item
Inventory
ManageAccount
Log-In
CODE DUPLICATION!
Customers
Check-Out
Shopping Carts
Client
Shopping
CancelPurchase
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
7
Complex Session: The Case For An Object Layer
Add-Item
Inventory
ManageAccount Product Log-In
Customers Check-Out
Customer Account
Shopping Carts
Client
Shopping
Shopping Cart
CancelPurchase
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
8
Logic vs. Data: Toward Encapsulation procedural architecture
LOGIC
2/2003
object-oriented architecture
DATA
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
9
Logic vs. Data: Reintroducing Separation (at a higher level) EJB architecture
session beans 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
entity beans 10
Logic vs. Data: Examples Session Beans
Entity Beans
Bank teller
Bank account
Credit card authorizer
Credit card
DNA sequencer
DNA strand
Order entry system
Order, Line item
Catalog engine
Product
Auction broker
Bid, Item
Order approval router
Purchase order
(after Mastering EJBs, Ed Roman, p231) 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
11
Logic vs. Data: Thick vs. Thin Bank teller session bean
complex bank operations 2/2003
simple conversational state (customer ID)
Bank account entity bean
elementary account ops (deposit, withdraw)
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
extensive account data 12
Definitions Given that Enterprise Beans are server-side components deployable in a distributed multi-tier environment: • Session Beans model the business’s processes: they perform work for clients calling them and are short-lived. • Entity Beans model the business’s fundamental underlying data: they are persistent objects stored in permanent storage. • Message-Driven Beans are a type of asynchronous Session Beans. 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
13
Feature Comparison Session Beans
Entity Beans
•
execute on behalf of a single client
•
•
can be transaction-aware
•
•
do not represent directly shared data in the database (but may access and update such data)
•
provide an object view of data in the database
•
relatively short-lived
•
can be long-lived
•
removed when container crashes
•
survive container crash (automatic state reset)
2/2003
allow shared access from multiple users is associated to a primary key (defining data uniqueness)
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
14
Concepts of Persistence • Serialization – bit-blobs written to storage media – not practical for selective search
• Object-to-Relational Mapping – data stored to and loaded from RDBMS – generally: 1 object class = 1 table, 1 object instance = 1 row, but not always – mapping scheme can be complex
• ODBMS – ideal for transparent object persistence, however not a widespread product
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
15
Bean Class Methods SessionBean
EntityBean
setSessionContext(ctx)
setEntityContext(ctx)
ejbCreate . . . ( . . . )
ejbFind . . . ( . . . )
ejbActivate()
ejbHome . . . ( . . . )
ejbPassivate()
ejbCreate( . . . )
ejbRemove()
ejbPostCreate( . . . ) ejbActivate() ejbLoad()
SessionBean & EntityBean
ejbStore()
businessMethod( . . . )
ejbPassivate()
get . . . ( . . . )
ejbRemove()
set . . . ( . . . )
unsetEntityContext()
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
16
EJB Trail • Session Beans – Stateless – Stateful • Entity Beans – Bean-Managed Persistence (BMP) – Container-Managed Persistence (CMP) • Message-Driven Beans
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
17
Without Object Pooling: Multiply And Waste Server Client #1
new Object()
if objects are “lightweight”: OK (as long as they are freed or garbage collected)
. . . but if they are expensive resources (connections, threads, beans, etc.): BAD!
Client #2
“You don’t want to build a new taxicab and hire a new driver for each incoming customer call.”
Client #3
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
18
Object Pooling: Conserve And Reuse Server Client #1
Pool
Pool.getObject()
Client #2
“Use a dispatch center (the pool) to assign taxicabs to customers.”
Client #3
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
19
Object Pooling: Cycle 1 2 3 4
2 3 4
3 4
1
1
2
3 4 5
4 5
1
4 5
1
3
2/2003
2
2
2
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
3
20
Object Pooling: Cycle 5
5 4
4
4
2 3
2
2 3
3
5
2
2
3 5
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
21
Entity Bean’s Lifecyle: The “Easter Eggs” Lab Does Not Exist
1. newInstance() 2. setEntityContext()
ejbHome()
ejbCreate()
2. ejbLoad()
1. unsetEntityContext() 2. Garbage Collect
Pooled
1. ejbActivate()
2’. ejbPassivate()
Ready
ejbFind() ejbSelect()
ejbRemove()
1’. ejbStore()
businessMethod() ejbSelect() 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
22
Entity Beans: BMP & CMP BMP Entity Beans
CMP Entity Beans
•
persistence logic is programmed in the bean class
•
persistence logic is declared in the deployment descriptors
•
big Java code for bean class
•
smaller Java code for bean class
– persistent fields & get/set methods – edit & search queries with JDBC
•
small XML deployment descriptors
– no persistent fields, abstract get/set – almost no JDBC
•
bigger XML deployment descriptors – persistent fields – EJB-QL search queries – container-specific DB mapping
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
23
Entity Bean’s Business Logic: BMP & CMP
class MyBean
abstract container-generated →
class MyBean class MyBeanSubclass extends MyBean
private instance fields
int xxx;
getXxx()
return xxx;
abstract
getXxx()
setXxx( arg )
xxx = arg;
abstract
setXxx( arg )
businessMethod( . . . )
...
2/2003
private instance fields
...
businessMethod( . . . )
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
24
Entity Bean’s Container Methods: BMP & CMP setEntityContext(ctx)
ctx = ctx
ctx = ctx
setEntityContext(ctx)
ejbFind . . . ( . . . )
SELECT
EJB-QL
ejbFind . . . ( . . . )
ejbHome . . . ( . . . )
SELECT
SELECT or ejbSelect()
ejbCreate( . . . )
INSERT
ejbPostCreate( . . . )
...
...
ejbPostCreate( . . . )
ejbActivate()
...
...
ejbActivate()
ejbLoad()
SELECT
post-SELECT
ejbLoad()
ejbStore()
UPDATE
pre-UPDATE
ejbStore()
ejbPassivate()
...
ejbRemove()
DELETE
pre-DELETE
unsetEntityContext()
ctx = null
ctx = null
set . . . ()
...
ejbHome . . . ( . . . ) ejbCreate( . . . )
ejbPassivate() ejbRemove() unsetEntityContext()
JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
JDBC 25
Entity Bean’s Container Methods: CMP
ejbSelect . . . ()
ctx = ctx
setEntityContext(ctx)
EJB-QL
ejbFind . . . ( . . . )
SELECT or ejbSelect()
ejbHome . . . ( . . . )
abstract
+ EJB-QL
set . . . ()
ejbCreate( . . . )
...
ejbPostCreate( . . . )
...
ejbActivate()
post-SELECT
ejbLoad()
pre-UPDATE
ejbStore()
... pre-DELETE
ctx = null
ejbPassivate() ejbRemove() unsetEntityContext() JDBC
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
26
Exception Handling
W Bu r a p sin so es m e sE in xc .!
2/2003
RUNTIME
De sig clar na e in tu re
CHECKED
Application Exceptions
• MyBusinessException •... • CreateException • RemoveException • FinderException • ObjectNotFoundExc.
System Exceptions
• NamingException • SQLException •...
• NullPointerException • IndexOutOfBoundsExc. • IllegalArgumentExc. •...
• EJBException • NoSuchEntityException
The caller’s fault or the internal business logic’s fault!
The system’s infrastructure’s fault!
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
! n p i tion a r W xcep BE J E
st Ju
le
. o.. g t
27
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public void setEntityContext(EntityContext ctx) {
ejbFind . . . ( . . . )
this.ctx = ctx; }
ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad()
public void unsetEntityContext()
ejbStore()
{
ejbPassivate()
}
this.ctx = null;
ejbRemove() unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
28
Entity Bean’s Container Methods: CMP → SAME
setEntityContext(ctx)
public void setEntityContext(EntityContext ctx) {
ejbFind . . . ( . . . )
this.ctx = ctx; }
ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad()
public void unsetEntityContext()
ejbStore()
{
ejbPassivate()
}
this.ctx = null;
ejbRemove() unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
29
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public Key ejbFind . . . ( args ) throws FinderException {
ejbFind . . . ( . . . ) [1]
try { ...get DB connection
ejbHome . . . ( . . . )
...prepare SELECT statement ...set args in statement
ejbCreate( . . . ) ejbPostCreate( . . . )
...execute statement query if (empty result) { ...throw FinderException } ...return key from result
ejbActivate() ejbLoad()
} catch (SQLException, NamingException) { ...throw EJBException } finally { ...close statement ...close connection }
ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
30
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public Collection ejbFind . . . ( args ) throws FinderException {
ejbFind . . . ( . . . ) [N]
try { ...get DB connection
ejbHome . . . ( . . . )
...prepare SELECT statement ...set args in statement
ejbCreate( . . . ) ejbPostCreate( . . . )
...execute statement query while (not empty result) { ...fill coll. with keys from result } ...return coll.
ejbActivate() ejbLoad()
} catch (SQLException, NamingException) { ...throw EJBException } finally { ...close statement ...close connection }
ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
31
Entity Bean’s Container Methods: CMP → IMPLEMENT IN EJB-QL
setEntityContext(ctx)
public Key/Collection ejbFind . . . ( args ) throws FinderException
ejbFind . . . ( . . . ) ejb-jar.xml
ejbHome . . . ( . . . )
. . . Container . . . find . . . args SELECT OBJECT(q) FROM . . . . . .
ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad() ejbStore() ejbPassivate() ejbRemove() unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
32
Entity Bean’s Container Methods: CMP → ABSTRACT METHOD AND EJB-QL
setEntityContext(ctx)
public abstract Collection ejbSelect . . . () throws FinderException;
ejbFind . . . ( . . . ) ejbSelect . . . () ejbHome . . . ( . . . )
ejb-jar.xml . . . Container . . . ejbSelect . . . SELECT q.xxx FROM . . . . . .
ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad() ejbStore() ejbPassivate() ejbRemove() unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
33
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public Value ejbHome . . . ( args ) throws BusinessException {
ejbFind . . . ( . . . )
try { ...get DB connection
ejbHome . . . ( . . . )
...prepare SELECT statement ...set args in statement
ejbCreate( . . . ) ejbPostCreate( . . . )
...execute statement query while (not empty result) { ...aggregate value from result } ...return value
ejbActivate() ejbLoad()
} catch (SQLException, NamingException) { ...throw EJBException } finally { ...close statement ...close connection }
ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
34
Entity Bean’s Container Methods: CMP → SAME OR USE ejbSelect()
setEntityContext(ctx)
public Value ejbHome . . . ( args ) throws BusinessException {
ejbFind . . . ( . . . )
try { ...get DB connection
ejbHome . . . ( . . . )
...prepare SELECT statement ...set args in statement
ejbCreate( . . . ) ejbPostCreate( . . . )
Collection c = ejbSelect()
...execute statement query while (not empty result) { ...aggregate value from result } ...return value
ejbActivate() ejbLoad()
} catch (SQLException, NamingException) { ...throw EJBException } finally { ...close statement ...close connection }
ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
35
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public Key ejbCreate( args ) throws CreateException { ...initialize fields with args try { ...get DB connection
ejbFind . . . ( . . . ) ejbHome . . . ( . . . )
...prepare INSERT statement ...set key & fields in statement
ejbCreate( . . . ) ejbPostCreate( . . . )
...execute statement update if (zero count) { ...throw CreateException } ...return key
ejbActivate() ejbLoad()
} catch (SQLException, NamingException) { ...throw EJBException } finally { ...close statement ...close connection }
ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
36
Entity Bean’s Container Methods: CMP → NO JDBC: set . . . () ONLY
setEntityContext(ctx)
public Key ejbCreate( args ) throws CreateException { ...initialize fields with args, using setXxx()
ejbFind . . . ( . . . ) ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate()
...return key
ejbLoad() ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
37
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public void ejbPostCreate( args ) {
ejbFind . . . ( . . . )
...use EJBObject, if needed }
ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad() ejbStore() ejbPassivate() ejbRemove() unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
38
Entity Bean’s Container Methods: CMP → SAME
setEntityContext(ctx)
public void ejbPostCreate( args ) {
ejbFind . . . ( . . . )
...use EJBObject, if needed }
ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad() ejbStore() ejbPassivate() ejbRemove() unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
39
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public void ejbRemove() throws RemoveException {
ejbFind . . . ( . . . )
try { ...get DB connection
ejbHome . . . ( . . . )
...prepare DELETE statement ...set key in statement
ejbCreate( . . . ) ejbPostCreate( . . . )
...execute statement update if (zero count) { ...throw RemoveException }
ejbActivate() ejbLoad()
} catch (SQLException, NamingException) { ...throw EJBException } finally { ...close statement ...close connection }
ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
40
Entity Bean’s Container Methods: CMP → NO JDBC: pre-DELETE ONLY
setEntityContext(ctx)
public void ejbRemove() throws RemoveException { ...possible pre-DELETE processing
ejbFind . . . ( . . . ) ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad() ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
41
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public void ejbActivate() {
ejbFind . . . ( . . . )
...acquire resources, if needed }
ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad()
public void ejbPassivate()
ejbStore()
{
ejbPassivate()
}
...release held resources, if any
ejbRemove() unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
42
Entity Bean’s Container Methods: CMP → SAME
setEntityContext(ctx)
public void ejbActivate() {
ejbFind . . . ( . . . )
...acquire resources, if needed }
ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad()
public void ejbPassivate()
ejbStore()
{
ejbPassivate()
}
...release held resources, if any
ejbRemove() unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
43
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public void ejbLoad() {
ejbFind . . . ( . . . )
try { ...get DB connection
ejbHome . . . ( . . . )
...prepare SELECT statement ...set key in statement
ejbCreate( . . . ) ejbPostCreate( . . . )
...execute statement query if (empty result) { ...throw NoSuchEntityException } ...get fields from result
ejbActivate() ejbLoad()
} catch (SQLException, NamingException) { ...throw EJBException } finally { ...close statement ...close connection }
ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
44
Entity Bean’s Container Methods: CMP → NO JDBC: post-SELECT ONLY
setEntityContext(ctx)
public void ejbLoad() {
ejbFind . . . ( . . . ) ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad() ejbStore() ejbPassivate()
...possible post-SELECT processing
ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
45
Entity Bean’s Container Methods: BMP setEntityContext(ctx)
public void ejbStore() {
ejbFind . . . ( . . . )
try { ...get DB connection
ejbHome . . . ( . . . )
...prepare UPDATE statement ...set key & fields in statement
ejbCreate( . . . ) ejbPostCreate( . . . )
...execute statement update if (zero count) { ...throw EJBException }
ejbActivate() ejbLoad()
} catch (SQLException, NamingException) { ...throw EJBException } finally { ...close statement ...close connection }
ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
46
Entity Bean’s Container Methods: CMP → NO JDBC: pre-UPDATE ONLY
setEntityContext(ctx)
public void ejbStore() {
ejbFind . . . ( . . . )
...possible pre-UPDATE processing
ejbHome . . . ( . . . ) ejbCreate( . . . ) ejbPostCreate( . . . ) ejbActivate() ejbLoad() ejbStore() ejbPassivate() ejbRemove()
}
unsetEntityContext() JDBC 2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
47
EJBs Are Single-Threaded
Container Strategy 1: serialize access to a single instance
Container Strategy 2: allow parallel access to multiple instances
2/2003
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
48
Entity Beans Are Single-Threaded
Container Strategy 1: serialize access to a single instance
Container Strategy 2: allow parallel access to multiple instances and keep data synchronized in DB
2/2003
ejbStore() ejbLoad()
CIS 386 - Enterprise JavaBeans: BMP and CMP Entity Beans
49