EJB 3.1 Programming - Timicoseddon-software/JEE/EJB Programming.pdf · Programming 1. Introduction to JEE 2. ... Java Enterprise Edition Overview of JEE and taking a look at Common
Embed Size (px)
344 x 292
429 x 357
514 x 422
599 x 487
Citation preview
EJB ProgrammingEJB 3.1 Programming
EJB 3.1 Programming
1. Introduction to JEE 2. Enterprise Java Beans 3. Stateless
Session Beans 4. Stateful Session Beans 5. EJB 3.1 Enhancements 6.
Object-Relational Mapping 7. Getting Started with JPA 8. Working
with Entities 9. JPA Query Language
10. More on JPA 11. Transactions 12. Callbacks and Interceptors 13.
Security 14. Java Messaging Service
Copyright ©2000-11 CRS Enterprises Ltd 5
Introduction to JEE
Java Enterprise Edition
Overview of JEE and taking a look at Common Application Servers and
Popular JEE Frameworks
Copyright ©2000-11 CRS Enterprises Ltd 7
JEE Java Versions
Java 1 (JDK 1.0 1.1) Java 2 (JDK 1.2 thru 1.6)
Java Enterprise Edition (JEE) Many technology areas:
JDBC, JNDI, RMI, Java IDL, Servlets, JSP, EJB2, EJB 3, JTS, JTA,
Java Mail, JAF, JMS, XML, Spring, Hibernate ...
Development Tools (include ...) javac Java compiler java Java
virtual machine javap Java decompiler jdb Command line debugger jar
Java archive generator keytool Certificate management jarsigner
Digital signing of jar files
Copyright ©2000-11 CRS Enterprises Ltd 8
Key Technologies JDBC
Java Database Connectivity
Servlets and JSPs http and http engine
EJB, RMI remote objects, JVM to JVM communication
JTS Java Transaction Service
Common Servers Tomcat
Development Environments Eclipse
http://www.eclipse.org/ many mirrors
www.yoxos.com MyEclipse
J2EE plugins already installed $29.95 for a 1-year subscription to
upgrades
Sun - NetBeans best for GUI builders
IBM - WebSphere Studio commercial offering - powerful and popular
IDE original developers of Eclipse
Borland - JBuilder commercial offering
App Server Architecture
Web Services Service Oriented Architecture
SOAP - Simple Object Access Protocol
defines message passing protocol
REST - Representational State Transfer
Remote Access to Services using Transport any transport will
do
http, JMS, TCP
replacing EJB type applications
data from databases, app servers, clients configuration
information
SAX and StAX Parsers push and pull streaming parsers low memory
footprint
Object Model Parsers DOM and Apache AXIOM build in-memory tree
often use SAX parser
Many APIs DOM, SAX, StaX, JDOM for manipulating XML Trax for
processing XSLT
Copyright ©2000-11 CRS Enterprises Ltd 14
Data Persistence Don't write JDBC code!
use a O/R mapping tool
Persistence API well supported Hibernate, iBatis, JDO, EJB 3,
Toplink
JDBC code automatically generated O/R tool queries database for
meta-data generates all the necessary Java classes and object
s
by inspecting tables and views often using code injection
customised classes can be generated using customised SQL
statements
Testing and Maintenance much faster development reduced testing and
maintenance generated code is reliable and efficient
Copyright ©2000-11 CRS Enterprises Ltd 15
EJB Architecture EJB Server provides underlying
infrastructure
Load balancing, fault tolerance, distribution, ....
EJB Container provides the middleware Transactions, persistence,
name service, resource p ooling
DBDB CartBean instances
much more than EJB container
Spring uses POJOs doesn't enforce contracts on your code
DBDB CartBean instances
Spring AOP
via stub and skeleton
Copyright ©2000-11 CRS Enterprises Ltd 19
Java Naming and Directory Interface JNDI provides standard
interface for naming and
directory services, such as Active Directory (Windows) LDAP (Unix)
details of underlying service concealed from Client
EJBs use JNDI for recovering stubs from a registry
Java ApplicationJava Application
JNDI APIJNDI API
Naming ManagerNaming Manager
CORBACORBA Active DirectoryActive Directory LDAPLDAP NISNIS
Copyright ©2000-11 CRS Enterprises Ltd 20
Container Services Transaction processing Integration with the
Persistence services
Java Persistence API (JPA)
Naming and directory services - JNDI
Security Java Cryptography Extension (JCE) JAAS
Remote procedure calls - RMI-IIOP
Load balancing and Failover
Enterprise Java Beans
EJBs
Discussing the five different types of EJB:
Stateless Session EJBs Stateful Session EJBs Singleton Session EJBs
Entity JPA Beans Message Driven Beans
Copyright ©2000-11 CRS Enterprises Ltd 25
EJB Specification Sun introduced EJBs in 1990s
Session EJBs to represent business objects Entity EJBs to represent
persistent objects Message Driven EJBs added to support JMS
Generally accepted that EJB2 specification is too complicated for
modern use difficult to write, test and maintain Session and
Message Driven beans still used occasio nally
EJB3 specification has rectified most of the proble ms uses
annotations similar to using the Spring Framework
Copyright ©2000-11 CRS Enterprises Ltd 26
Why Use EJBs? EJBs run in a Container which provides
services:
transaction processing integration with Java Persistence API (JPA)
concurrency control events using Java Message Service naming and
directory services (JNDI) security - Java Cryptography Extension
(JCE) and JAA S deployment of software components in an application
server remote procedure calls using RMI-IIOP exposing business
methods as Web Services
You don't want to provide these services yourself get them for free
with your EJB container
Copyright ©2000-11 CRS Enterprises Ltd 27
5 Types of EJB EJB specification discusses five types of
components:
stateless session beans stateful session beans singleton session
beans entity beans message-driven beans
In EJB3, entity beans are replaced by JPA Entities
Copyright ©2000-11 CRS Enterprises Ltd 28
Stateless Session EJB Stateless session beans:
provide non-conversational services do not maintain state on behalf
of the client are synchronous do not survive EJB server crashes are
maintained in memory
Calls can be handled by any instance with the same results
Copyright ©2000-11 CRS Enterprises Ltd 29
Stateful Session EJB Stateful session EJBs:
provide conversational interaction store state on behalf of the
client are associated with a single client (pinned) are synchronous
are maintained in memory do not survive EJB server crashes
Copyright ©2000-11 CRS Enterprises Ltd 30
Singleton Session EJB Singleton Session Beans
business objects with global shared state
Concurrent access to the singleton is managed by: the
container
Container-managed concurrency, CMC or by the bean itself
Bean-managed concurrency, BMC
Container-managed concurrency @Lock
designates whether a read lock or a write lock will be used for a
method call
@Startup Singleton Session Beans can explicitly request to b e
instantiated
when the EJB container starts up
Copyright ©2000-11 CRS Enterprises Ltd 31
Entity EJB Entity EJBs:
are representations of persistent data are an in-memory "copy" of
the data in the persiste nt store
Specification deeply flawed heavily over-engineered require an
enormous effort to maintain in a project difficult to test
Entity EJBs are no longer used in practice!! use JPA Entities
instead
Copyright ©2000-11 CRS Enterprises Ltd 32
Message -Driven Beans Message-driven beans (MDB):
are asynchronous stateless components behave similarly to stateless
session beans are JMS message consumers
Clients do not interact directly with MDBs Container manages
connections often used with Web services
Copyright ©2000-11 CRS Enterprises Ltd 33
Client
Remote buy sell
The Big Picture - Session EJBs EJBs use RMI stubs and skeletons to
communicate
Remote object is used to deliver business method ca lls
There are a pool of remote objects per EJB class
Copyright ©2000-11 CRS Enterprises Ltd 34
The Role of the Remote Object The Remote object implements the
Proxy pattern
client cannot talk to the EJB directly must channel requests
through the remote object
Remote objects intercept client requests inject extra code before a
method is called on the EJB (middleware
services) apply security constraints to requests can throw
exceptions RMI does not use this mechanism
Generating Middleware services is performed by the EJB container
this means the developer can concentrate on develop ing
business
methods huge saving in development effort
Copyright ©2000-11 CRS Enterprises Ltd 35
Client
Who does What? You write the EJB and Client code
Container adds other services
Java EE Application Structure
Entities An entity is an object that holds data
Entities are persistent
In Java EE 5 / 6: An entity is a POJO You provide metadata to map
the entity class to a d atabase table You use JPA to load/save
objects to/from the databa se
JPA versions: Java EE 5: JPA 1 Java EE 6: JPA 2
Copyright ©2000-11 CRS Enterprises Ltd 38
Operation at Run Time At start-up EJB server creates pool of
beans
beans are assigned to clients when client first acc esses a bean
when a bean is released by client or times out, it is returned to
pool
Bean poolEJB objects
Client 1Client 1
Client 2Client 2
Client 3Client 3
Packaging and Deployment Web applications
packaged in a WAR file
EJBs are packaged in a JAR file
Combined applications (EJBs and Web) are packaged in an EAR
file
Copyright ©2000-11 CRS Enterprises Ltd 40
EJB Jar contains EJB code Deployment Descriptors
EJB Jar Files
Copyright ©2000-11 CRS Enterprises Ltd 41
WAR and EJB Jar files can be deployed as one using an EAR
file
Ear Files
Stateless Session Beans
Stateless Session Beans
Creating Stateless Session beans and writing web based and Java
client applications
Copyright ©2000-11 CRS Enterprises Ltd 45
Session Bean Interfaces and Classes EJB 3.0
define a remote and/or local interface define the bean class
EJB 3.1 interfaces are optional
EJB object
EJB bean
methods on bean, via the EJB object
container generates the proxy provides container services
you define the bean class implement business methods
Copyright ©2000-11 CRS Enterprises Ltd 46
Defining Metadata You can provide metadata to accompany session
beans
transactional requirements, security, etc.
There are 3 ways to provide metadata Implicit defaults Annotations
Deployment descriptors
Are annotations or deployment descriptors better? Discuss
Copyright ©2000-11 CRS Enterprises Ltd 47
Overview of Stateless Session Beans Stateless session beans do not
retain client-specif ic state
between method calls lightweight and scalable
If a client invokes a series of methods on a statel ess session
bean… the methods might be executed on different bean ins tances
this doesn't matter at all, because stateless sessi on beans do not
contain
any client-specific state
Local and Remote Interfaces Local and remote interfaces
specifies the 'business methods' for your bean annotate an
interface with @Local or @Remote
package demos.sessionbeans.ejb; import javax.ejb.Local;
@Local public interface TempConverterLocal {
}
} package demos.sessionbeans.ejb; import javax.ejb.Remote;
@Remote public interface TempConverterRemote {
}
}
Defining Exceptions Remote/local interface methods can throw
applicatio n
exceptions
public InvalidTempException() { super();
public InvalidTempException() { super();
}
}
Copyright ©2000-11 CRS Enterprises Ltd 50
Ensuring Consistency If you want to expose the same business
interface
remotely and locally…
}
}
Copyright ©2000-11 CRS Enterprises Ltd 51
Defining the Bean Class In EJB 3.0, the implementation class is a
POJO
Just annotate the class with @Stateless or @ Stateful
package demos.sessionbeans.ejb;
import javax.ejb.Stateless;
implements TempConverterRemote, TempConverterLocal {
}
implements TempConverterRemote, TempConverterLocal {
}
Stateless Bean Life Cycle ...
Copyright ©2000-11 CRS Enterprises Ltd 53
... Stateless Bean Life Cycle A bean class can define methods to be
invoked durin g
bean start-up and shut-down
@Stateless public class TempConverterBean
@PreDestroy public void myPreDestroyMethod() {
}
@PreDestroy public void myPreDestroyMethod() {
}
Copyright ©2000-11 CRS Enterprises Ltd 54
Client's View (Injection) Can inject a bean reference into a Java
client:
Declare a static variable of the remote interface t ype Annotate
the variable with @EJB
Can tell the EJB container how to resolve the injec tion:
Can inject a reference to a bean on a different ser ver:
import javax.ejb.EJB; import
demos.sessionbeans.ejb.TempConverterRemote; @EJB private static
TempConverterRemote tempConverterBea n;
import javax.ejb.EJB; import
demos.sessionbeans.ejb.TempConverterRemote; @EJB private static
TempConverterRemote tempConverterBea n;
@EJB(mappedName="MyTempConverterBean") private static
TempConverterRemote tempConverterBea n;
@EJB(mappedName="MyTempConverterBean") private static
TempConverterRemote tempConverterBea n;
@EJB(mappedName="corbaname:iiop:localhost:3700#MyTe
mpConverterBean") private static TempConverterRemote
tempConverterBea n;
@EJB(mappedName="corbaname:iiop:localhost:3700#MyTe
mpConverterBean") private static TempConverterRemote
tempConverterBea n;
Copyright ©2000-11 CRS Enterprises Ltd 55
Client's View (JNDI) You can access bean using JNDI lookup...
To look-up a bean by its remote interface type:
To look-up a bean by its mappedName:
To look-up a bean on a specific server:
InitialContext context = new InitialContext(); bean =
(TempConverterRemote)context.lookup(
"demos.sessionbeans.ejb.TempConverterRemote");
"demos.sessionbeans.ejb.TempConverterRemote");
Hashtable env = new Hashtable();
env.put("org.omg.CORBA.ORBInitialHost", "localhost" );
env.put("org.omg.CORBA.ORBInitialPort", "3700"); InitialContext
context = new InitialContext(env); bean =
(TempConverterRemote)context.lookup("MyTempC onverterBean");
Hashtable env = new Hashtable();
env.put("org.omg.CORBA.ORBInitialHost", "localhost" );
env.put("org.omg.CORBA.ORBInitialPort", "3700"); InitialContext
context = new InitialContext(env); bean =
(TempConverterRemote)context.lookup("MyTempC onverterBean");
Copyright ©2000-11 CRS Enterprises Ltd 56
Client Application After acquiring access to a bean, use it as
follows :
public class Main
private static void testStatelessBean() { // Assign via injection
or manual JNDI lookup TempConverterRemote bean;
try { System.out.println("212F = " + bean.fToC(212) + "C") ;
System.out.println("100C = " + bean.cToF(100) + "F") ;
} catch (InvalidTempException ex) {…}
private static void testStatelessBean() { // Assign via injection
or manual JNDI lookup TempConverterRemote bean;
try { System.out.println("212F = " + bean.fToC(212) + "C") ;
System.out.println("100C = " + bean.cToF(100) + "F") ;
} catch (InvalidTempException ex) {…}
Copyright ©2000-11 CRS Enterprises Ltd 57
Using the Bean in a Web App ... A Web app can access an EJB via its
remote interfac e
public class MyServlet extends HttpServlet {
@EJB private TempConverterRemote bean; protected void doGet(…) …
{
out.println("212F = " + bean.fToC(212) + "C"); out.println("100C =
" + bean.cToF(100) + "F");
public class MyServlet extends HttpServlet {
@EJB private TempConverterRemote bean; protected void doGet(…) …
{
out.println("212F = " + bean.fToC(212) + "C"); out.println("100C =
" + bean.cToF(100) + "F");
Using injectionUsing injection
protected void doGet(…) … {
(TempConverterRemote)context.lookup("MyTempConverte rBean");
out.println("212F = " + bean.fToC(212) + "C"); out.println("100C =
" + bean.cToF(100) + "F");
protected void doGet(…) … {
(TempConverterRemote)context.lookup("MyTempConverte rBean");
out.println("212F = " + bean.fToC(212) + "C"); out.println("100C =
" + bean.cToF(100) + "F");
Copyright ©2000-11 CRS Enterprises Ltd 59
Stateful Session Beans
Stateful Session Beans
Creating Stateful Session beans and writing web based and Java
client applications
Copyright ©2000-11 CRS Enterprises Ltd 61
Overview of Stateful Session Beans Stateful session beans hold
conversations with a
particular client spans multiple method calls
Stateful session beans must retain state between method calls state
is specific to a particular client
Subsequent method invocations get pinned to the same EJB
Copyright ©2000-11 CRS Enterprises Ltd 62
Defining the Remote / Local Interface Remote and local
interfaces
are the same as for stateless session beans
package demos.sessionbeans.ejb;
}
}
Copyright ©2000-11 CRS Enterprises Ltd 63
Defining the Bean Class ... Bean class must be annotated with
@Stateful
indicates it's a stateful session bean
Bean class must implement the business methods that are specified
in the remote / local interfaces bean class (and almost always
does) have instance v ariables instance variables are preserved in
a stateful sess ion beans
EJB 3.1 Specification ... you don't have to define any interfaces
simplifies definition of bean
Copyright ©2000-11 CRS Enterprises Ltd 64
... Defining the Bean Class
@Stateful public class ShoppingCartBean implements ShoppingCa
rtRemote {
private Vector<String> items = new Vector<String>() ;
public void addItem(String productName) {
items.addElement(productName);
} public void removeItem(String productName) {
items.removeElement(productName);
} public Vector<String> getItems() {
@Stateful public class ShoppingCartBean implements ShoppingCa
rtRemote {
private Vector<String> items = new Vector<String>() ;
public void addItem(String productName) {
items.addElement(productName);
} public void removeItem(String productName) {
items.removeElement(productName);
} public Vector<String> getItems() {
Stateful Session Life Cycle ...
Copyright ©2000-11 CRS Enterprises Ltd 66
... Stateful Session Life Cycle Example showing how to define life
cycle methods:
@Stateful public class ShoppingCartBean
Using the Bean in a Client App public class Main {
@EJB private static ShoppingCartRemote shoppingCartBean;
public static void main(String[] args) {
testStatefulBean(); }
testStatefulBean(); }
System.out.println("Item: " + e.nextElement()); }
System.out.println("Item: " + e.nextElement()); }
Copyright ©2000-11 CRS Enterprises Ltd 68
EJB in Web App ... You can access stateful session beans in Web
apps
but you must be very careful...
Do not use injection for stateful session beans each servlet
instance gets its own session bean but servlets are shared across
clients ...
this probably isn't what you want! you want each client to get its
own session bean
that why the HttpSession object must be used
Use manual JNDI lookup initially look up the bean using JNDI
and insert the bean proxy into HTTPSession object next time get the
bean from HTTPSession (not JNDI)
this way, each client has its own session bean
Copyright ©2000-11 CRS Enterprises Ltd 69
... EJB in Web App (HTML)
<h2>Manage your Shopping Cart</h2>
<form action="ShoppingCartServlet" method="get"> <input
type="text" name="txtItem" /> <input type="submit" value="Add
to cart" />
</form>
<form action="ShoppingCartServlet" method="get"> <input
type="text" name="txtItem" /> <input type="submit" value="Add
to cart" />
</form>
ShoppingCartServlet
@EJB(name="ejb/Cart",
beanInterface=demos.sessionbeans.ejb.ShoppingCartLo
cal.class)
protected void doGet(…) { // Get existing ShoppingCart bean from
HTTP session , or lookup new one. HttpSession sess =
request.getSession(); ShoppingCartLocal bean =
(ShoppingCartLocal)sess.ge tAttribute("Cart"); if (bean == null) {
InitialContext context = new InitialContext(); bean =
(ShoppingCartLocal)context.lookup("java:comp /env/ejb/Cart");
sess.setAttribute("Cart", bean);
}
// Invoke business method on bean, to add item to s hopping cart.
bean.addItem(request.getParameter("txtItem"));
// Redisplay HTML form and shopping cart JSP. …
} }
protected void doGet(…) { // Get existing ShoppingCart bean from
HTTP session , or lookup new one. HttpSession sess =
request.getSession(); ShoppingCartLocal bean =
(ShoppingCartLocal)sess.ge tAttribute("Cart"); if (bean == null) {
InitialContext context = new InitialContext(); bean =
(ShoppingCartLocal)context.lookup("java:comp /env/ejb/Cart");
sess.setAttribute("Cart", bean);
}
// Invoke business method on bean, to add item to s hopping cart.
bean.addItem(request.getParameter("txtItem"));
// Redisplay HTML form and shopping cart JSP. …
} }
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"
%>
<%-- Does session scope have a "Cart" attribute? --% >
<c:if test="${not empty sessionScope.Cart}">
<%-- Get items in ShoppingCart bean, and assign to l ocal
variable --%> <c:set var="itemsInCart"
value="${sessionScope.Car t.items}" />
<%-- Iterate through the items --%> Items in shopping cart:
<br/> <ul> <c:forEach var="item"
items="${itemsInCart}">
<li>${item}</li> </c:forEach> </ul>
</c:if>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"
%>
<%-- Does session scope have a "Cart" attribute? --% >
<c:if test="${not empty sessionScope.Cart}">
<%-- Get items in ShoppingCart bean, and assign to l ocal
variable --%> <c:set var="itemsInCart"
value="${sessionScope.Car t.items}" />
<%-- Iterate through the items --%> Items in shopping cart:
<br/> <ul> <c:forEach var="item"
items="${itemsInCart}">
<li>${item}</li> </c:forEach> </ul>
</c:if>
DisplayShoppingCart.jsp
EJB 3.1 Enhancements
EJB 3.1 Enhancements
Looking at new features in EJB 3.1 such as Singleton Beans
Copyright ©2000-11 CRS Enterprises Ltd 75
Singleton Beans EJB implementing the Singleton pattern
all client requests are directed through the contai ner to a sole
target instance
instance’s state is shared by all requests EJB must be designed as
thread-safe may result in blocking (waiting) for new requests
Design very carefully locking and synchronization required to
ensure thre ad safety may have diasterous effect on performance if
poorly designed
Copyright ©2000-11 CRS Enterprises Ltd 76
... Singleton Beans
this.cache = new HashMap(); }
} public void put(String key,Object value){
this.cache.put(key, value); }
this.cache = new HashMap(); }
} public void put(String key,Object value){
this.cache.put(key, value); }
... Singleton Beans Singleton EJB can be injected into
Servlets:
public class MyServlet extends HttpServlet { @EJB SingletonBean
singleton;
@Override public void init(){
..... }
}
@Override public void init(){
..... }
}
... Singleton Beans (locking)
@javax.ejb.AccessTimeout(timeout=15,unit=TimeUnit.S ECONDS)
@javax.ejb.Lock(LockType.READ) public String accessorMethod()
{...}
@javax.ejb.Lock(LockType.WRITE) public void mtuatorMethod()
{...}
}
Bean Managed locking DIY using synchronize and volatile
Copyright ©2000-11 CRS Enterprises Ltd 79
No Interface Beans EJB3 required clients to uselocal or remote
busines s
interfaces good design practice but having to replicate the
interface methods in th e class is tedious
In EJB 3.1 interfaces are no longer required
@Stateless public class MyBean {
} }
} }
Asynchronous Methods ... Message Driven Beans allow the use of
asynchronous
actions methods easy to use still need to configure JMS
If you don't need JMS you can use @Asynchronous annotation to state
that an EJB retur ns immediately
from the invocation.
IllegalArgumentException, EncryptionException {
@Asynchronous public Future<String> asyncMethod()
throws
IllegalArgumentException, EncryptionException {
Copyright ©2000-11 CRS Enterprises Ltd 81
... Asynchronous Methods Client View
call long running method asynchronously method returns immediately
client then free to do other work the client can pick up the result
when ready
Future<String> future = ejb.asyncMethod(input); // returns
immediately
// do other work until ... // ready to get result result =
future.get(10,TimeUnit.SECONDS);
Future<String> future = ejb.asyncMethod(input); // returns
immediately
// do other work until ... // ready to get result result = future.
get (10,TimeUnit.SECONDS);
Copyright ©2000-11 CRS Enterprises Ltd 82
Timer Service
}
}
Copyright ©2000-11 CRS Enterprises Ltd 83
Injection or Lookup As an alternative to injection, clients of an
EJB c an obtain
a reference to the session bean's proxy object usin g JNDI
Only possibility when injection is not available standalone remote
Java SE clients when it's necessary to programmatically determine
wh ich bean to obtain
InitialContext ctx = new InitialContext(); CustomerServiceLocal
customerService =
(CustomerServiceLocal) ctx.lookup("java:module/Cust
omerService");
(CustomerServiceLocal) ctx.lookup("java:module/Cust
omerService");
Looking up EJB Resources JEE Specification defines global JNDI
namespace
and related namespaces that map scopes of a Java EE application
used by applications to portably retrieve reference s to components
applies to session beans only
Global JNDI name has the following syntax
java:global[/<app-name>]/<module-name>/<bean-name>[
!<fully- qualified-interface-name>]
java:global[/<app-name>]/<module-name>/<bean-name>[
!<fully- qualified-interface-name>]
java:global/fooejb/FooBean!com.acme.Foojava:global/fooejb/FooBean!com.acme.Foo
Copyright ©2000-11 CRS Enterprises Ltd 85
EJBs in an EAR File EJB packaged inside an ear file:
EAR file: myapp .ear EJB jar file: myejb .jar
N.B. Interface is optional
Copyright ©2000-11 CRS Enterprises Ltd 86
Standalone EJB jars EJB packaged as standalone module:
EJB jar file: myejb .jar
N.B. Interface is optional
package com.acme; @Stateless public class MyBeanImpl implements
MyBean { ... }
package com.acme ; @Stateless public class MyBeanImpl implements
MyBean { ... }
Copyright ©2000-11 CRS Enterprises Ltd 87
Other JNDI Namespaces java:app
allows component executing within a JEE application to access an
EJB in the same application
java:module allows a component executing within a JEE module to
access an EJB in
the same module
EJBs Expose Multiple JNDI Names EJB packaged as standalone
module:
EJB jar file: myejb .jar
java:global/shared/Shared!com.acme.SharedBean
java:global/shared/Shared!com.acme.SharedRemote
java:app/shared/Shared!com.acme.SharedBean
java:app/shared/Shared!com.acme.SharedRemote
java:module/Shared!com.acme.SharedBean
java:module/Shared!com.acme.SharedRemote
java:global/shared/Shared!com.acme.SharedBean
java:global/shared/Shared!com.acme.SharedRemote
java:app/shared/Shared!com.acme.SharedBean
java:app/shared/Shared!com.acme.SharedRemote
java:module/Shared!com.acme.SharedBean
java:module/Shared!com.acme.SharedRemote
Copyright ©2000-11 CRS Enterprises Ltd 90
Object-Relational Mapping
Object-Relational Mapping
Overview of Object Model to Relational Database mapping (ORM).
Introducing Hibernate and the JPA.
Copyright ©2000-11 CRS Enterprises Ltd 92
Object Models vs. Relational Models Object models:
Designed to serve the needs of the application Organize data into
abstract concepts to solve the d omain problem Encapsulate
functionality for a particular applicat ion
Relational models: Designed to serve the needs of the business
Typically optimized for performance and space Typically already
exists Typically used by lots of applications Typically managed by
a separate DBA group
Copyright ©2000-11 CRS Enterprises Ltd 93
Object/Relational Mapping Object Relational mapping (ORM)
Java Persistence API (JPA) Hibernate Java Data Objects (JDO)
Tools FireStorm/DAO is a code generator, automatically ge nerating
DAO code
for accessing relational databases
Granularity Object Orientation
Relational Database DB model takes normalization
and performance into account e.g. flatten "value" types into
columns
in the main table (or use UDTs)
-employeeID -name -salary -region
EMPLOYEES table
Inheritance Object Orientation
You use inheritance for IS-A relationships Substitutability allows
polymorphism
Relational Database No such thing as inheritance Various ORM
strategies to simulate E.g. table per class More on this
later...
-employeeID -name -salary -region
EMPLOYEES table
Associations Object Orientation
You use associations for HAS-A relationships Based on object
references (i.e. addresses) Multiplicity: whatever you choose!
Navigability: uni-directional or bi-directional
Relational Database Based on PK-FK relationships Parent provides
PK, child provides FK For many-to-many, need a join table No
concept of navigability
-employeeID -name -salary -region
EMPLOYEEID [FK] DESCRIPTION LEVEL
Copyright ©2000-11 CRS Enterprises Ltd 97 97
Identity / Equality Object Orientation
Equality means "same value" Check via equals()
Relational Database Based on PK value Question: use "surrogate
keys" or
"natural keys"
emp1 == emp2
Including composition, inheritance, and polymorphis m
Non-intrusive persistence Persistent classes don't need to inherit
/ implemen t anything
Object queries Ability to query across object relationships, witho
ut PK / FK
considerations
Efficient fetching strategies Lazy fetching (useful for large data
items) Eager fetching (useful for avoiding n+1 selects nig htmare!)
Caching strategies
JPA and Hibernate do all this Use metadata (XML or Java
annotations) Provide APIs for managing objects/data
JPA and Hibernate do all this Use metadata (XML or Java
annotations) Provide APIs for managing objects/data
Copyright ©2000-11 CRS Enterprises Ltd 99 99
JPA and Hibernate JSR 220 aimed to simplify EJBs
… because EJB 2.x was bulky and cumbersome
This led to the advent of EJB 3.0 Streamlines session beans and
MDBs Simplifies entities – this is the Java Persistence A PI
(JPA)
The JPA specification is implemented by… Full-blown Java EE
application servers
E.g. JBoss A/S, WebSphere, Oracle A/S, GlassFish, e tc. JBoss
Hibernate
Lightweight, open-source implementation of the JPA standard Also
has a native API, and non-standard extensions Often used in
conjuction with the Spring Framework
Copyright ©2000-11 CRS Enterprises Ltd 100 100
JPA Versions JPA 1.0
Core OR/M features Available in Java EE 5 and Hibernate 3.3 and
earlie r
JPA 2.0 (December 2009) Expanded object/relational mapping
functionality (c ollections of
embedded objects, ordered lists) Criteria query API Standardization
of query 'hints' Standardization of additional metadata to support
D DL generation Support for validation Available in Java EE 6 and
Hibernate 3.5
Copyright ©2000-11 CRS Enterprises Ltd 102
Getting Started with JPA
Getting Started with JPA
Fundamentals of JPA mappings for simple tables and mapping
relationships between tables
Copyright ©2000-11 CRS Enterprises Ltd 104
Mapping Options Metadata for mapping classes to tables
Identify which classes map to which tables Identify which class
fields/properties map to which table columns Use convention over
configuration
You can define mappings in XML: Define POJO class (free from
database table clutter ) Define JPA mapping file to specify
mapping
Or you can define mappings using annotations: Java Persistence API
(JPA) annotations (javax.persi stence.*)
Copyright ©2000-11 CRS Enterprises Ltd 105
Persistence.xml Using EclipseLink as persistence provider
<?xml version="1.0" encoding="UTF-8"?> <persistence
version="2.0" xmlns="http://java.sun.c om/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc e"
xsi:schemaLocation="http://java.sun.com/xml/ns/pers istence
http://java.sun.com/xml/ns/persistence/persistence_
2_0.xsd">
<persistence-unit name="CustomerEB">
<class>myejb.Customer</class> <properties>
<property name="eclipselink.target-database" value=
"ORACLE"/> <property name="eclipselink.jdbc.driver"
value="ora cle.jdbc.driver.OracleDriver"/> <property
name="eclipselink.jdbc.url" value="jdbc:o
racle:thin:@localhost:1521:xe"/> <property
name="eclipselink.jdbc.user" value="java" /> <property
name="eclipselink.jdbc.password" value="o racle"/>
</properties> </persistence-unit>
<persistence-unit name="CustomerEB">
<class>myejb.Customer</class> <properties>
<property name="eclipselink.target-database" value=
"ORACLE"/> <property name="eclipselink.jdbc.driver"
value="ora cle.jdbc.driver.OracleDriver"/> <property
name="eclipselink.jdbc.url" value="jdbc:o
racle:thin:@localhost:1521:xe"/> <property
name="eclipselink.jdbc.user" value="java" /> <property
name="eclipselink.jdbc.password" value="o racle"/>
</properties> </persistence-unit>
What Can You Annotate? Classes
@Entity Indicates that a class is mapped to a table @Table
Indicates the table name (if different)
Either fields or properties @Id Identity column @Column Column with
different name than field/prope rty @OneToMany, @ManyToOne,
etc.
Copyright ©2000-11 CRS Enterprises Ltd 107
Listing Mapped Classes If you use JPQL:
No need to list mapped classes - they are detected a
utomatically
<?xml version="1.0" encoding="UTF-8"?> <persistence
version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc e"
xsi:schemaLocation="http://java.sun.com/xml/ns/pers istence
http://java.sun.com/xml/ns/persistence/persistence_ 2_0.xsd">
<persistence-unit name="ch13">
</properties> </persistence-unit>
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc e"
xsi:schemaLocation="http://java.sun.com/xml/ns/pers istence
http://java.sun.com/xml/ns/persistence/persistence_ 2_0.xsd">
<persistence-unit name="ch13">
</properties> </persistence-unit>
Copyright ©2000-11 CRS Enterprises Ltd 108
What about the Mapping Files? You don't need the JPA or Hibernate
XML mapping fil es
replaced by annotations
Copyright ©2000-11 CRS Enterprises Ltd 109
1. Mapping a Class to a Table @Entity marks the class as an entity
@Table maps it to a database table
(named EMPLOYEES in the MYSCHEMA schema) the class must have a
no-arg public or protected co nstructor can be serializable, handy
for distributed systems
import javax.persistence.*; @Entity @Table(name="EMPLOYEES",
schema="MYSCHEMA") public class Employee {
private int employeeId = -1; private String name; private double
dosh;
public Employee() { // Empty no-arg constructor.
} }
private int employeeId = -1; private String name; private double
dosh;
public Employee() { // Empty no-arg constructor.
} }
You can set name="xxx" for use in queries (default name is
unqualified class name)
Fields/properties are automatically persistable (default column
name is same)
@Table is optional (default table name is the entity name)
Copyright ©2000-11 CRS Enterprises Ltd 110 110
Equality vs. Identity In OO terminology:
Identity means "address" Check via ==
Equality means "same value" Check via equals()
In a relational database schema: Based on PK value Question: use
"surrogate keys" or
"natural keys"
emp1 == emp2
Smith 10000 UK
Copyright ©2000-11 CRS Enterprises Ltd 111 111
Mapping Entity Identity ... Every entity class requires a
serializable identity (PK)
Typically int or long Uniquely identifies bean instances, and maps
them t o specific rows in
the database table
To designate the identity property/field: Annotate a property/field
in the entity class with @Id Placement of @Id determines whether
property accessors or fields are
used for persistence
Specify how primary keys are generated: Annotate identity
property/field with @GeneratedVal ue Various strategies (default is
GenerationType.AUTO)
Copyright ©2000-11 CRS Enterprises Ltd 112 112
... Mapping Entity Identity
private int employeeId = -1; private String name; ………… @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) public int
getEmployeeId() {
return employeeId; }
} }
private int employeeId = -1; private String name; ………… @Id
@GeneratedValue (strategy = GenerationType.IDENTITY) public int
getEmployeeId() {
return employeeId; }
} }
Copyright ©2000-11 CRS Enterprises Ltd 113
Mapping Persistent Data ... In JPA 2, you can annotate an entity to
enforce
persistence mode: @javax.persistence. Access (AccessType.FIELD)
@javax.persistence. Access (AccessType.PROPERTY)
By default, all fields/properties are persisted Use
@javax.persistence. Transient to indicate a non-persistent
field/property
By default, field/property names are assumed to be the same as
database column names Use @javax.persistence. Column to specify a
different column name
Copyright ©2000-11 CRS Enterprises Ltd 114
... Mapping Persistent Data In Employees entity, annotate the dosh
property
because the db column name is different (salary)
import javax.persistence.*;
private int employeeId = -1; private String name; private double
dosh;
… @Column(name="Salary") public double getDosh() {
return dosh; }
} }
private int employeeId = -1; private String name; private double
dosh;
… @Column(name="Salary") public double getDosh() {
return dosh; }
} }
Copyright ©2000-11 CRS Enterprises Ltd 115 115
2. Associations ... Relational databases contain relations
One-to-one One-to-many Many-to-one Many-to-many
Classes can have associations Multiplicity: one-to-one, or
one-to-many Directionality: uni-directional or bi-directional
JPA can cope with all this In your classes, you specify how the OO
association s relate to DB
relations
Copyright ©2000-11 CRS Enterprises Ltd 116
Mapping Simple Associations ... To give you an overview for now,
we'll consider the
following scenario An employee has many skills
This is a unidirectional, one-to-many collection... Employee object
has a collection of Skill objects Skill objects have no knowledge
of Employee object
Employee
Skill
Skill
Skill
Skill
Associated Classes
package mypackage; … public class Employee {
private int employeeId = -1; private String name; private double
salary; private String region; private Set<Skill> skills =
new HashSet<Skill>();
// Getters/setters, biz methods … }
package mypackage; … public class Employee {
private int employeeId = -1; private String name; private double
salary; private String region; private Set<Skill> skills =
new HashSet<Skill>();
// Getters/setters, biz methods … }
JPA insists collection variables are typed as interfaces (e.g. Set)
rather than as classes (e.g. HashSet)
package mypackage;
private int skillId = -1; private String description; private int
level;
// Getters and setters … }
private int skillId = -1; private String description; private int
level;
// Getters and setters … }
... Mapping Simple Associations import javax.persistence.*;
@Entity @Table(name="EMPLOYEES", schema="MYSCHEMA") public class
Employee {
private int employeeId = -1; private String name; private
Set<Skill> skills = new HashSet<Skill>();
@OneToMany(cascade=CascadeType.ALL) @JoinColumn(name="EMPLOYEEID")
public Set<Skill> getSkills() {
return skills; }
} }
@Entity @Table(name="EMPLOYEES", schema="MYSCHEMA") public class
Employee {
private int employeeId = -1; private String name; private
Set<Skill> skills = new HashSet<Skill>();
@OneToMany(cascade=CascadeType.ALL) @JoinColumn(name="EMPLOYEEID")
public Set<Skill> getSkills() {
return skills; }
} }
Copyright ©2000-11 CRS Enterprises Ltd 119
@Transient Don't persist a field/property
Additional Property Mappings
@Temporal(TemporalType.DATE) public Date getJoiningDate() { …
}
@Temporal(TemporalType.DATE) public Date getJoiningDate() { …
}
@Lob @Basic(fetch=FetchType.LAZY) public byte[] getPhoto() { …
}
@Lob @Basic(fetch=FetchType.LAZY) public byte[] getPhoto() { …
}
@Enumerated Persists an enum type
@Enumerated(EnumType.STRING) public MyJobTitleEnum getJobTitle() {
… }
@Enumerated(EnumType.STRING) public MyJobTitleEnum getJobTitle() {
… }
@Transient public double getMonthlySalary() { … }
@Transient public double getMonthlySalary() { … }
Copyright ©2000-11 CRS Enterprises Ltd 120
Mapping an Entity to Multiple Tables You can map an entity class to
multiple tables
Use @SecondaryTable to indicate secondary table tha t supplies some
of the fields/properties for your entity
Use @PrimaryKeyJoinColumn to indicate PK column nam e In @Column
mappings, set the table attribute
@Entity @Table(name="EMPLOYEES", schema="MYSCHEMA")
@SecondaryTable(name="CONTRACTS", schema="MYSCHEMA" ,
pkJoinColumns=@PrimaryKeyJoinColumn(name="EMPLOYEEI D")) public
class Employee {
… @Column(table="CONTRACTS") @Temporal(TemporalType.DATE) public
Date getStartDate() { … }
@Entity @Table(name="EMPLOYEES", schema="MYSCHEMA") @SecondaryTable
(name="CONTRACTS", schema="MYSCHEMA",
pkJoinColumns=@PrimaryKeyJoinColumn(name="EMPLOYEEI D")) public
class Employee {
… @Column(table="CONTRACTS") @Temporal(TemporalType.DATE) public
Date getStartDate() { … }
Copyright ©2000-11 CRS Enterprises Ltd 121
3. Strategies for Generating IDs JPA-standard strategies
AUTO / native IDENTITY / identity SEQUENCE / sequence TABLE (JPA
only)
Custom ID generators Composite keys
Using @IdClass Using @Embeddable
JPA-Standard Strategies JPA defines 4 standard strategies for
generating
identifiers in an entity:
AUTO This is a commonly-used strategy in JPA
Lets JPA pick the strategy to use Uses identity, sequence, or hilo
strategy, dependin g on the capabilities of
the underlying database
@Entity … public class Employee {
e.g. Microsoft SQL Server, Sybase, DB2, MySQL
@Entity … public class Employee {
@Entity … public class Employee {
E.g. Oracle, DB2, PostgreSQL Efficiently generates sequential
IDs
To define a sequence generator: Annotate entity class or ID with
@SequenceGenerator (…)
name - [Required] Unique generator name that entity c lasses can
use sequenceName - Name of database sequence object from which to
obtain primary key allocationSize - Amount to increment by
initialValue - Initial value when allocating id numbe rs from the
generator
name - [Required] Unique generator name that entity c lasses can
use sequenceName - Name of database sequence object from which to
obtain primary key allocationSize - Amount to increment by
initialValue - Initial value when allocating id numbe rs from the
generator
Copyright ©2000-11 CRS Enterprises Ltd 126
... SEQUENCE
…
…
Copyright ©2000-11 CRS Enterprises Ltd 127
TABLE ... You can use a database table to hold generated valu
es
This approach is completely portable
To define a table generator: Annotate entity class or ID with
@TableGenerator(…)
name - [Required] Unique generator name that entity c lasses can
use table - Table name that contains generated IDs catalog -
Catalog name for table schema - Schema name for table pkColumnName
- Name of PK column in table pkColumnValue - PK value in generator
table, identifi es which row is generated valueColumnName - Name of
column that stores the last value generated allocationSize - Amount
to increment by initialValue - Initial value when allocating id
numbe rs from the generator
name - [Required] Unique generator name that entity c lasses can
use table - Table name that contains generated IDs catalog -
Catalog name for table schema - Schema name for table pkColumnName
- Name of PK column in table pkColumnValue - PK value in generator
table, identifi es which row is generated valueColumnName - Name of
column that stores the last value generated allocationSize - Amount
to increment by initialValue - Initial value when allocating id
numbe rs from the generator
Copyright ©2000-11 CRS Enterprises Ltd 128
... TABLE
table = "ID_GENERATOR_TABLE", pkColumnName = "ID_NAME",
pkColumnValue = "EMPLOYEES_GENERATOR", valueColumnName =
"ID_VALUE", allocationSize = 100)
public int getEmployeeId() { … } …
table = "ID_GENERATOR_TABLE", pkColumnName = "ID_NAME",
pkColumnValue = "EMPLOYEES_GENERATOR", valueColumnName =
"ID_VALUE", allocationSize = 100)
public int getEmployeeId() { … } …
Composite Keys Database tables can have composite keys
Comprised of multiple PK columns in the table For example, imagine
the following in an EMPLOYEES table:
EMPLOYEEID = partial PK OFFICEID = partial PK EMPLOYEENAME SALARY
etc …
To cope with composite keys in your entity bean: Define a primary
key class Use annotations to associate your bean class with t he PK
class
Either: @IdClass and @Id Or: @Embeddable and @EmbeddedId
Copyright ©2000-11 CRS Enterprises Ltd 130
@IdClass and @Id Define a PK class that specifies the composite
fiel ds
Annotate the bean class with @IdClass Use @Id annotations to map
fields/properties to PK fields
@Entity @IdClass(EmployeePK.class) … public class Employee
implements Serializable {
private int employeeId, officeId; // Fields for t he PK. @Id public
int getEmployeeId() { … } // Plus setter. @Id public int
getOfficeId() { … } // Plus setter. …
@Entity @IdClass (EmployeePK.class) … public class Employee
implements Serializable {
private int employeeId, officeId; // Fields for t he PK. @Id public
int getEmployeeId() { … } // Plus setter. @Id public int
getOfficeId() { … } // Plus setter. …
public class EmployeePK implements Serializable { private int
employeeId, officeId; // Columns that comprise the PK. // Plus
getters/setters, no-arg ctor, equals(), and hashCode(). …
public class EmployeePK implements Serializable { private int
employeeId, officeId; // Columns that comprise the PK. // Plus
getters/setters, no-arg ctor, equals(), and hashCode(). …
Copyright ©2000-11 CRS Enterprises Ltd 131
@Embeddable and @EmbeddedId Enables you to embed a primary key
directly in your bean
Annotate PK class with @Embeddable and define @Colu mn maps
Use the PK in your entity bean class, via @Embedded Id
@Embeddable public class EmployeePK implements Serializable {
private int employeeId, officeId; // Columns that comprise the PK.
@Column public int getEmployeeId() { … } // Plus setter. @Column
public int getOfficeId() { … } // Plus setter.
@Embeddable public class EmployeePK implements Serializable {
private int employeeId, officeId; // Columns that comprise the PK.
@Column public int getEmployeeId() { … } // Plus setter. @Column
public int getOfficeId() { … } // Plus setter.
@Entity … public class Employee implements Serializable {
private EmployeePK pk; // PK object. @EmbeddedId public EmployeePK
getPk() { … } // Plus setter.
@Entity … public class Employee implements Serializable {
private EmployeePK pk; // PK object. @EmbeddedId public EmployeePK
getPk() { … } // Plus setter.
Copyright ©2000-11 CRS Enterprises Ltd 132 132
4. Value Types Entities:
Persistable objects, e.g. Employee Has a persistent identity
(equivalent to a PK in th e database) Has independent lifespan
Support shared references Persisted via references (FK)
Value types: Low-level "data" (e.g. Address), belong to another
entity instance No database identifier Lifespan is bounded to that
of its owning entity Don't support shared references If you have a
ref to a value type, it embeds in own er entity's row
Copyright ©2000-11 CRS Enterprises Ltd 133
Embedded Objects All rows come from the same table
A single row is mapped to multiple objects Highly efficient, no
joining required
Person class Address class
Copyright ©2000-11 CRS Enterprises Ltd 134
Using JPA Annotations ... To define the "main" class
Annotate embedded field/property with @Embedded
@Entity public class Person {
private int personId = -1; private String firstName; private String
lastName;
@Embedded private Address address; …
private int personId = -1; private String firstName; private String
lastName;
@Embedded private Address address; …
... Using JPA Annotations To define "embeddable" class
Annotate class with @Embeddable Annotate fields/properties if
needed
@Embeddable public class Address {
// Getters and setters… }
// Getters and setters… }
Working with Entities
Working with Entities
Controlling JPA Entities using an Entity Manager. Looking at how to
create, inject and test JPA Entity beans.
Copyright ©2000-11 CRS Enterprises Ltd 140
Creating an Entity Manager ... JUnit 4 setup
when testing JPA directly
@BeforeClass // before any test public static void
setUpBeforeClass() throws Except ion {
factory = Persistence.createEntityManagerFactory(PE
RSISTENCE_UNIT_NAME); entityManager =
factory.createEntityManager(); tx =
entityManager.getTransaction();
} @AfterClass // after all tests public static void
tearDownAfterClass() throws Exce ption {
entityManager.close(); factory.close();
@BeforeClass // before any test public static void
setUpBeforeClass() throws Except ion {
factory = Persistence.createEntityManagerFactory(PE
RSISTENCE_UNIT_NAME); entityManager =
factory.createEntityManager(); tx =
entityManager.getTransaction();
} @AfterClass // after all tests public static void
tearDownAfterClass() throws Exce ption {
entityManager.close(); factory.close();
... Creating an Entity Manager
tx.begin(); }
entityManager.persist(customer); tx.commit();
tx.begin(); }
entityManager.persist(customer); tx.commit();
For examples, see EmployeeRespositoryImpl.java
Clear the persistence context, causing all managed entities to
become detached
EntityManager Mgment Methods Method Description
find(), getReference() Find an entity by its primary key
refresh()
remove()
flush()
Refresh the state of an entity with up-to-date data from the
database
Removes an entity from the database
Flushes pending changes of managed entities to the database
detach() Detaches an entity from the persistence context
persist() Persist (i.e. insert) an entity into the database
contains() Determine if an entity is attached to a persistence
context
merge() Merge the state of a detached entity with an attached
entity
clear()
Entity States Transient
An entity has just been created using new() The entity is not yet
associated with a persistenc e context (i.e. doesn't
have a persistent ID yet)
Persistent (or "attached" or "managed") E.g. entity has been loaded
from the DB by EntityMa nager JPA detects whether attached entities
are "dirty" JPA synchronizes state with the database at "flush"
time
Detached Entity was attached to a persistence context, which is now
closed See next section for details
Copyright ©2000-11 CRS Enterprises Ltd 144 144
Flush Modes The persistence context has a "flush mode"
Determines when flushing occurs
JPA has 2 flush modes: FlushModeType.AUTO (default)
When unit of work completes Before executing new queries When you
call flush() on EntityManager
FlushModeType.COMMIT Only at commit time
To set the flush mode: Call setFlush() on EntityManager, to apply
for all queries Or call setFlush() on Query, to apply for specific
query only
Copyright ©2000-11 CRS Enterprises Ltd 145
Making an Entity Persistent To make a new entity persistent:
Create an entity using new() Set its values, invoke its methods and
call persist ()
when persist() returns, entity will be a managed en tity within the
entity manager’s persistence context
public void persistEmployee(String name, double sal ary, String
region) {
EntityManager em = factory.createEntityManager(); Employee emp =
new Employee(name, salary, region);
em.getTransaction().begin(); em.persist(emp);
em.getTransaction().commit();
EntityManager em = factory.createEntityManager(); Employee emp =
new Employee(name, salary, region);
em.getTransaction(). begin() ; em.persist(emp);
em.getTransaction(). commit() ;
em.close(); }
Copyright ©2000-11 CRS Enterprises Ltd 146
Finding an Object by Primary Key There are two ways to retrieve an
existing row (int o an
entity) by primary key: find()
if PK found, loads entity into memory immediately
getReference()
if PK found, (potentially lazily) loads entity into memory else
throws EntityNotFoundException
public Employee getEmployee(int employeeId) {
em.close(); return emp;
em.close(); return emp;
Miscellaneous Useful Methods To see if an entity is attached:
boolean contains(Object entity)
To clear attached entities: void clear()
To modify an entity: Call any methods you like on the entity But
make sure the entity is a managed instance, so the
EntityManager
can detect the changes!
Copyright ©2000-11 CRS Enterprises Ltd 148 148
Refreshing an Entity To refresh the in-memory state of an entity
with th e latest
data from the database, call refresh(): void refresh(Object
entity)
Example:
// Refresh an Employee entity with latest data from the database.
// This will overwrite any changes you've made to t he entity in
memory.
em.refresh(employee1);
// Refresh an Employee entity with latest data from the database.
// This will overwrite any changes you've made to t he entity in
memory.
em.refresh(employee1);
Copyright ©2000-11 CRS Enterprises Ltd 149
Removing an Entity To remove an entity from the database, call
remove( )
void remove(Object entity) Note, it must be a managed entity in the
persistenc e context i.e application must have already loaded or
accesse d the entity
public void removeEmployee(int employeeId) {
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
em.remove(emp); em.getTransaction().commit();
em.remove(emp); em.getTransaction().commit();
Transaction Management ... It's important to ensure modification
operations ar e
enclosed in a transaction scope otherwise the changes will never be
persisted
Transaction management depends on the environment i n which your
code is executing… Transactions in a Java EE container
environment:
standard Java Transaction API (JTA) is used annotate session beans
to ensure a transaction is r unning
Transactions in a Java SE application: you must explicitly begin()
and commit()/rollback() transactions see example on the previous
slide
Copyright ©2000-11 CRS Enterprises Ltd 151
... Transaction Management
EntityManager em = factory.createEntityManager(); Employee emp1 =
em.find(Employee.class, fromEmploye eId); Employee emp2 =
em.find(Employee.class, toEmployeeI d);
if (emp1 != null && emp2 != null) {
em.getTransaction().begin(); emp1.setDosh(emp1.getDosh() - amount);
emp2.setDosh(emp2.getDosh() + amount);
if (willCommit) em.getTransaction().commit(); else
em.getTransaction().rollback();
EntityManager em = factory.createEntityManager(); Employee emp1 =
em.find(Employee.class, fromEmploye eId); Employee emp2 =
em.find(Employee.class, toEmployeeI d);
if (emp1 != null && emp2 != null) {
em.getTransaction().begin(); emp1.setDosh(emp1.getDosh() - amount);
emp2.setDosh(emp2.getDosh() + amount);
if (willCommit) em.getTransaction().commit(); else
em.getTransaction().rollback();
Managing Detached Entities When you detach() an
EntityManager:
The specified entity is detached
When you close() an EntityManager: The persistence context is
cleared, i.e. all entiti es are detached
Detached entities: You can still use detached entities You can also
re-attach them later
Copyright ©2000-11 CRS Enterprises Ltd 153 153
Identity of Detached Entities ... You can guarantee the identity
for:
Entities in the same unit-of-work
You can't guarantee the identity for: Detached entities Entities
from different persistence contexts
Employee a = em.find(Employee.class, 42); Employee b =
em.find(Employee.class, 42);
if (a == b) { …………} // This is true
Employee a = em.find(Employee.class, 42); Employee b =
em.find(Employee.class, 42);
if (a == b) { …………} // This is true
Employee a = em1.find(Employee.class, 42); Employee b =
em2.find(Employee.class, 42);
if (a == b) { …………} // This is false
Employee a = em1.find(Employee.class, 42); Employee b =
em2.find(Employee.class, 42);
if (a == b) { …………} // This is false
Copyright ©2000-11 CRS Enterprises Ltd 154 154
... Identity of Detached Entities The non-guarantee of entity
identity is a problem i n the
following scenario: You want to put multiple entities into a
collection (e.g. a Set), e.g. as part
of a one-to-many association
It's a problem because… If the entities came from different
persistence con texts, or are detached,
then 2 entities that actually represent the same DB row won't be
considered "equal" when you put them in the Set
So the Set will contain both entities Argh!
Solution: Ensure that 2 entities that represent the same data base
row really are
considered "equal" You achieve this by overriding equals() and
hashCod e() Strongly recommended!
Copyright ©2000-11 CRS Enterprises Ltd 155
Implementing equals() and hashCode() @Override
public boolean equals(Object other) { boolean result = false; if
(other instanceof Employee) {
Employee otherEmp = (Employee)other; result = (this.employeeId ==
otherEmp.employeeId);
} return result;
}
@Override public boolean equals (Object other) { boolean result =
false; if (other instanceof Employee) {
Employee otherEmp = (Employee)other; result = (this.employeeId ==
otherEmp.employeeId);
} return result;
public class Employee {
}
public class Employee {
}
Copyright ©2000-11 CRS Enterprises Ltd 156
Re-attaching Detached Entities To re-attach a detached entity into
a persistence c ontext:
Call merge() on the EntityManager
This is how merge() works: If there is a persistent instance with
the same ide ntifier currently
associated with the persistence context , copy the state of the
given entity onto the persistent instance
If there is no persistent instance currently associ ated with the
persistence context , try to load it from the datab ase, or create
a new persistent instance
The persistent instance is returned The given instance does not
become associated with the persistence
context , it remains detached
JPA Query Language
JPA Query Language
Investigating the JPA Query Language and its relation to the Entity
Manager
Copyright ©2000-11 CRS Enterprises Ltd 160 160
Several Ways to Query Data Get an entity by its primary key Query
for entities using JPA QL Query for entities using Criteria
queries
not supported in JPA 1
Execute standard SQL
Persistence Units - Recap The persistence.xml file defines
persistence units
<?xml version="1.0" encoding="UTF-8"?> <persistence …………
>
<persistence-unit name="MyPU" transaction-type="JTA"> …………
database connection info …………
</persistence-unit>
</persistence>
<persistence-unit name="MyPU" transaction-type="JTA"> …………
database connection info …………
</persistence-unit>
</persistence>
persistence.xmlpersistence.xml
Copyright ©2000-11 CRS Enterprises Ltd 162 162
Creating an EntityManager in Java EE To get an EntityManager
object, you use "injection"
via the @PersistenceContext annotation
Note: Stateful session beans can create extended persiste nce
contexts EJB 3.0 allows you to define long-living EntityMana gers
that live beyond
the scope of a JTA transaction this is called an Extended
Persistence Context all object instances remain managed beyond a
single transaction
@PersistenceContext(unitName = "MyPU") EntityManager em;
@PersistenceContext(unitName = "MyPU") EntityManager em;
@PersistenceContext(unitName = "MyPU",
type=PersistenceContextType.EXTENDED)
Copyright ©2000-11 CRS Enterprises Ltd 163 163
Persisting an Entity Bean To create a new bean in memory and
persist into a d b:
persist the bean by calling EntityManager persist() method void
persist(Object entity)
@Stateless public class MyBean implements MyBeanRemote {
@PersistenceContext(unitName = "MyPU") EntityManager em;
} }
@PersistenceContext(unitName = "MyPU") EntityManager em;
} }
Copyright ©2000-11 CRS Enterprises Ltd 164
Getting an Entity by Primary Key In JPQL, call these EntityManager
methods:
find(), returns null if not found getReference(), throws
EntityNotFoundException
public static void getEmployee(EntityManager em, in t employeeID)
{
Employee emp = (Employee) em.find(Employee.class, e mployeeID); if
(emp == null) {
System.out.println("No employee with ID " + employe eID); } else
{
System.out.println("Employee with ID " + emp.getEmp loyeeId() + "
is " + emp.getName());
} }
Employee emp = (Employee) em.find(Employee.class, e mployeeID); if
(emp == null) {
System.out.println("No employee with ID " + employe eID); } else
{
System.out.println("Employee with ID " + emp.getEmp loyeeId() + "
is " + emp.getName());
} }
Named and Positional Parameters
public static void getEmployeesEarning(EntityManage r em, double
minSalary) {
Query query = em.createQuery("from Employee e where e.salary >=
:minSalary"); query.setParameter("minSalary", minSalary);
// or... // Query query = em.createQuery("from Employee e wh ere
e.salary >= ?1"); // query.setParameter(1, minSalary);
List<Employee> emps = query.getResultList(); for (Employee
emp: emps)
System.out.println(emp.getName() + "\t" + emp.getSa lary());
}
// or... // Query query = em.createQuery("from Employee e wh ere
e.salary >= ?1"); // query.setParameter( 1, minSalary);
List<Employee> emps = query.getResultList(); for (Employee
emp: emps)
System.out.println(emp.getName() + "\t" + emp.getSa lary());
}
TypedQuery<Employee> query = em.createQuery("from E
mployee…", Employee.class); TypedQuery<Employee> query =
em.createQuery("from E mployee…", Employee.class);
Entity name, not table name
Copyright ©2000-11 CRS Enterprises Ltd 166
Using a WHERE Clause
public static void getEmployeesIn(EntityManager em, String regions)
{
Query query = em.createQuery( "select e from Employee e where
e.region in (:regio ns)");
List<String> regionsList = new ArrayList<String>();
Collections.addAll(regionsList, regions);
query.setParameter("regions", regionsList);
List<Employee> emps = query.getResultList();
System.out.println("Employees in one of regions "); for (Employee
emp: emps) {
System.out.println("\t" + emp.getName() + "\t" + em p.getRegion());
}
}
public static void getEmployeesIn(EntityManager em, String regions)
{
Query query = em.createQuery( "select e from Employee e where
e.region in (:regions) ");
List<String> regionsList = new ArrayList<String>();
Collections.addAll(regionsList, regions);
query.setParameter("regions", regionsList);
List<Employee> emps = query.getResultList();
System.out.println("Employees in one of regions "); for (Employee
emp: emps) {
System.out.println("\t" + emp.getName() + "\t" + em p.getRegion());
}
}
Example usage:
Function Description
concat(s1, s2) Returns concatenated string
substring(s, offset, len) Returns substring, from 1-based
offset
trim( [both|leading|trailing] ch from s ) Trims leading and/or
trailing occurrences of specified ch
length(s) Returns length of string
locate(searchStr, str, offset) Returns 1-based position of
searchStr, starting at offset in str
abs(n), sqrt(n), mod(x,y) Math functions
size(c) Returns size of collection, or 0 if empty
Query query = session.createQuery( "from Employee e where
lower(e.region) = 'london'");
Query query = session.createQuery( "from Employee e where
lower(e.region) = 'london'");
Copyright ©2000-11 CRS Enterprises Ltd 168 168
Ordering Rows You can use an ORDER BY clause to order the rows in
a
result set The optional ASC and DESC keywords indicate ascendi ng
or descending
order (the default is ascending)
public static void getSortedEmployees(EntityManager em) {
Query query = em.createQuery( "from Employee e order by e.region,
e.name");
List<Employee> emps = query.getResultList();
System.out.println("Employees sorted by region, the n by name ");
for (Employee emp: emps) { System.out.println("\t" + emp.getName()
+ "\t" + em p.getRegion());
} }
Query query = em.createQuery( "from Employee e order by e.region,
e.name");
List<Employee> emps = query.getResultList();
System.out.println("Employees sorted by region, the n by name ");
for (Employee emp: emps) { System.out.println("\t" + emp.getName()
+ "\t" + em p.getRegion());
} }
Copyright ©2000-11 CRS Enterprises Ltd 169
Paging Results To achieve paging, use the following methods on a q
uery
Query setFirstResult(int startAt) Query setMaxResults(int
max)
Improves performance, makes your application scalab le
public void getPagedEmployees(EntityManager em, int startAt, int
max) {
Query query = em.createQuery("from Employee");
query.setFirstResult(startAt); query.setMaxResults(max);
List<Employee> emps = query.getResultList();
System.out.println("Page of Employees, starting at " + startAt);
for (Employee emp: emps) {
System.out.println("\t" + emp.getName() + "\t" + em p.getRegion());
}
}
Query query = em.createQuery("from Employee");
query.setFirstResult(startAt); query.setMaxResults(max);
List<Employee> emps = query.getResultList();
System.out.println("Page of Employees, starting at " + startAt);
for (Employee emp: emps) {
System.out.println("\t" + emp.getName() + "\t" + em p.getRegion());
}
}
Copyright ©2000-11 CRS Enterprises Ltd 170
Projections ... The examples so far have selected all columns of a
table
Each row becomes an entire object, and is added to the persistence
cache
It's also possible to select a subset of columns e.g. an employee's
ID, name, and salary Each row is returned as an Object[], with an
entry per column
results are not stored in the persistence cache
public static void getEmployeeProjections(EntityMan ager em) {
String sql = "select e.name, e.salary from Employee e"; Query query
= em.createQuery(sql);
List<Object[]> emps = query.getResultList();
System.out.println("Employee projection data"); for (Object[] info
: emps) {
}
List<Object[]> emps = query.getResultList();
System.out.println("Employee projection data"); for (Object[] info
: emps) {
}
... Projections Projection can create new objects
dynamically…
package mypackage; public class EmployeeSummary {
private String name; private double salary;
public EmployeeSummary(String name, double salary) { this.name =
name; this.salary = salary;
} }
private String name; private double salary;
public EmployeeSummary(String name, double salary) { this.name =
name; this.salary = salary;
} }public static void getEmployeeSummaries(EntityManag er em)
{
Query query = em.createQuery( "select new
mypackage.EmployeeSummary(e.name, e.sal ary) from Employee
e");
List<EmployeeSummary> empSums = query.getResultLst( );
System.out.println("Employee summaries"); for (EmployeeSummary
empSum: empSums) {
System.out.printf("\t%s earns %.2f\n", empSum.getNa me(),
empSum.getSalary()); }
}
List<EmployeeSummary> empSums = query.getResultLst( );
System.out.println("Employee summaries"); for (EmployeeSummary
empSum: empSums) {
System.out.printf("\t%s earns %.2f\n", empSum.getNa me(),
empSum.getSalary()); }
}
More on JPA
More on JPA
Investigation some of the more advanced features of JPA
Entities
Copyright ©2000-11 CRS Enterprises Ltd 176
Lazy Loading Small Objects
default to EAGER loading lazy loading is not a significant
performance optim ization best practice to eagerly load basic
properties, and lazily load ones that
may be large and infrequently accessed
Large Objects by default, collection items are loaded lazily
Copyright ©2000-11 CRS Enterprises Ltd 177
Eager Fetching EAGER is default with simple objects To enable eager
fetching for large objects
i.e. disable lazy fetching
@Lob // Note that this is a binary large object @Basic(fetch =
FetchType.LAZY, optional = true) // Don't load this by default;
it's an expensive op eration. // Only load when requested. private
byte[ ] image;
@Lob // Note that this is a binary large object @Basic(fetch =
FetchType.LAZY, optional = true) // Don't load this by default;
it's an expensive op eration. // Only load when requested. private
byte[ ] image;
Copyright ©2000-11 CRS Enterprises Ltd 178
Cascading Changes You can tell JPA to automatically
save/update/delet e
children that belong to the parent
@OneToOne(cascade={CascadeType.ALL}) @PrimaryKeyJoinColumn private
Address address;
@OneToOne(cascade={CascadeType.ALL}) @PrimaryKeyJoinColumn private
Address address;
Copyright ©2000-11 CRS Enterprises Ltd 179 179
Dirty Checking Gotcha JPA automatically checks whether values in a
persis tent
bean have been modified
For simple properties, it checks the value If a "getter" returns a
different object than the o ne originally populated... JPA detect
changes to the copy, if its value has ch anged
For collection properties, it checks the identity It a "getter"
returns a different collection object than the one populated… JPA
will always think the collection has changed, b ecause its identity
is
different JPA will attempt to update the collection regardles
s
Copyright ©2000-11 CRS Enterprises Ltd 180
Read-Only Getters JPA does not automatically manage
associations
between objects Especially an issue when you have bi-directional as
sociations
You have to manage these associations yourself, wit h your own code
To ensure both ends of the association remain in sy nch
To simplify matters: Define a helper method in the parent class, to
mana ge all the object
association details Define the collection getter to return a
read-only collection, to prevent the
client from updating collection directly
Copyright ©2000-11 CRS Enterprises Ltd 181
Non-Public Setters The parent entity doesn't have to expose a
public s etter
for its children It only needs to be public if you want to expose
it as part of your parent's
external interface
An alternative approach: Provide an alternative method that allows
client to modify children
private void setSkills(Set<Skill> skills) { this.skills =
skills;
}
}
}
}
Exceptions in Getters/Setters If you use getters/setters for
persistence…
JPA will call getters/setters during object loading /storing What
happens if the getter/setter throws an excepti on?
If the exception is a runtime exception: JPA rolls back the current
transaction
If the exception is a checked exception: JPA wraps it in a runtime
exception JPA doesn't roll back the exception
If you don't want JPA/Hibernate to potentially fail during
getters/setters… Use field-persistence, rather than getter/setter
pe rsistence
Copyright ©2000-11 CRS Enterprises Ltd 183
Named Queries ... You can define named queries using
annotations
You can annotate a persistent class with @NamedQuer y and/or
@NamedNativeQuery
@NamedQueries( { @NamedQuery(
... }) @Entity @Table(name="EMPLOYEES") public class Employee { ...
}
@NamedQueries( { @NamedQuery(
... }) @Entity @Table(name="EMPLOYEES") public class Employee { ...
}
183
... Named Queries In JPQL, to use a named query:
Call the JPA Query createNamedQuery() method
public static void getEmployeesInSalaryRange(Entity Manager em,
double min, double max) {
Query query = em.createNamedQuery("getEmployeesInSa laryRangeJpa");
query.setParameter(1, min); query.setParameter(2, max);
System.out.printf("\t%s\t%.2f\n", emp.getName(),emp .getSalary());
}
}
Query query = em.createNamedQuery("getEmployeesInSa laryRangeJpa");
query.setParameter(1, min); query.setParameter(2, max);
System.out.printf("\t%s\t%.2f\n", emp.getName(),emp .getSalary());
}
}
Transactions
Transactions
Discussing what a transaction is and how to use transactions with
EJBs and JPA Enties
Copyright ©2000-11 CRS Enterprises Ltd 188
A set of operations either: succeeds completely in modifying state
of set of
objects or fails leaving the set of objects in their original
state
A transaction is formally defined by the set of properties known by
the acronym ACID Atomic Consistent Isolated Durable
Two major types Pessimistic and Optimistic
Transactions
import javax.transaction.*;
public void transfer(Account from, Account to, doubl e amount)
{
try { UserTransaction tx = ctx.getUserTransaction(); tx.begin();
from.debit(amount); to.credit(amount); tx.commit();
} catch (Exception e) { tx.rollback();
public void transfer(Account from, Account to, doubl e amount)
{
try { UserTransaction tx = ctx.getUserTransaction(); tx.begin() ;
from.debit(amount); to.credit(amount); tx.commit() ;
} catch (Exception e) { tx.rollback() ;
Copyright ©2000-11 CRS Enterprises Ltd 190
Transactions may span two or more distributed system s databases
message queues
Travel Agent
Travel Agent
Two-Phase Commit Protocol Prepare Phase
Transaction Manager
Transaction Manager
prepare
prepared
prepare
prepared
Each Resource Manager logs results of transaction in persistent
storage (but does not actually commit it)
Commit Phase
Transaction Manager
Transaction Manager
commit
committed
commit
committed
Each Resource Manager commits results of transaction (e.g. to a
database)
Copyright ©2000-11 CRS Enterprises Ltd 192
Managing Transactions with EJBs EJB server provides a transaction
manager
Bean can access multiple databases in a single trans action
Transaction demarcation can be container-managed or
bean-managed
Container-managed transaction demarcation Commit and rollback
decisions are handled automatic ally by container Transaction
policy is specified via attribute(s) in bean's deployment
descriptor Separates transactional behaviour from business logi c
Reduces complexity of bean implementation
Bean-managed transaction demarcation Transaction demarcation must
be handled programmati cally (via JTA) Increases complexity of bean
implementation Can only be used with Session EJBs
Copyright ©2000-11 CRS Enterprises Ltd 193
Declarative Transaction Management To use declarative transaction
management:
Annotate bean (or methods) with @TransactionAttribu te Specify the
type of transaction you need
TransactionAttributeType options:
}
}
NOT_SUPPORTED Transaction Type
TransactionAttributeType.NOT_SUPPORTED
T1T1
ClientClient
If client has transaction, bean method is included in it
If client doesn't have transaction, bean method doe sn't create
one
T1T1 T1T1
"SUPPORTS" Bean
"SUPPORTS" Bean
ClientClient
REQUIRED Transaction Type TransactionAttributeType.REQUIRED
If client has a transaction, bean method is include d in it
If client doesn't have a transaction, bean method c reates
one
T1T1
Client
ClientClient
REQUIRES_NEW Transaction Type
TransactionAttributeType.REQUIRES_NEW
If client has a transaction, bean method creates ne w one
anyway
If client doesn't have a transaction, bean method c reates
one
Client
ClientClient "MANDATORY" Bean
If client doesn't have a transaction, exception!
Client
ClientClient
If client has a transaction, exception!
If client doesn't have transaction, bean method doe sn't create
one
Client
T1T1
public class MyBean {
}
} }
}
} }
Throw an application exception (annotated to cause rollback)
Causing a Transaction to Rollback 3 ways for a bean method to cause
a transaction rol lback:
@ApplicationException(rollback=true) public class MyAppException
extends Exception {…}
@ApplicationException(rollback=true) public class MyAppException
extends Exception {…}
Copyright ©2000-11 CRS Enterprises Ltd 201
public interface javax.transaction.UserTransaction { void begin()
throws NotSupportedException, SystemException; void commit() throws
RollbackException, HeuristicMixedException, ... int getStatus()
throws SystemException; void rollback() throws
IllegalStateException, SecurityException, ... void
setRollbackOnly() throws IllegalStateException, ... void
setTransactionTimeout(int seconds) throws SystemException;
}
}
@TransactionManagement(TransactionManagementType.BEAN ) public
class InitializerBean {
@TransactionManagement(TransactionManagementType.BEAN ) public
class InitializerBean {
Interleaved transactions must not interfere with each other, but
Excessive locking can lead to
poor performance
If transaction is a read operation, some degree of interference may
be acceptable
Types of interference: Dirty reads
A transaction reads uncommitted update from another transaction
Non-repeatable reads
Multiple reads in the same transaction return different results
Phantom reads
A transaction reads the wrong results because the d atabase was
simultaneously updated by another transaction
Account Bean
Account Bean
Teller Bean
Teller Bean
Teller Bean
Teller Bean
Isolation Levels
Transaction can read uncommitted data Dirty reads, nonrepeatable
reads, and phantom reads can occur
Transaction cannot read uncommitted data Dirty reads cannot occur
Nonrepeatable reads, and phantom reads can occur
One transaction cannot change data that is being read by another
Dirty reads and nonrepeatable reads cannot occur Phantom reads can
occur
Transaction has exclusive access to data Dirty reads, nonrepeatable
reads, and phantom reads cannot occur
TRANSACTION_READ_UNCOMMITTED
TRANSACTION_READ_COMMITTED
TRANSACTION_REPEATABLE_READ
TRANSACTION_SERIALIZABLE
Pessimistic Transactions
clientclient objectobject
write lock
get state
modify state
lock object for the entire period pattern works well if
contention is likely no collision recovery required
Copyright ©2000-11 CRS Enterprises Ltd 205
Optimistic Transactions
clientclient objectobject
read lock
get state
modify state
write lock
get state
minimize the time object is locked hoping a collision doesn't
occur pattern works well if
contention is unlikely
In a distributed environment communications failures can happen if
communication between the transaction manager an d a
recoverable
resource is not possible for an extended period of time the
recoverable resource may decide to unilaterally commit or
rollback
Such decisions are called a heuristic decisions one of the worst
errors that may happen in a transa ction system parts of the
transaction being committed while othe r parts are rolled
back
violates consistency part of A CID possible data corruption
Heuristic Exceptions
Callbacks and Interceptors
Callbacks and Interceptors
Looking at callbacks on JPA Entities and Interceptors for EJBs.
Seeing how this relates to Aspect Oriented Progamming (cross
cutting)
Copyright ©2000-11 CRS Enterprises Ltd 210
Aspect Oriented Programming Cross-cutting modules in a system
authentication, logging, resource pooling, administ ration,
performance, persistence
modulemodule modulemodule
modulemodule modulemodule
Entity Callbacks and Listeners Entity Beans can be notified
when database is updated
Why? perhaps a database trigger will fire
might involve intewraction with other entities you might want to
log events other cross cutting services
@javax.persistence.PrePersist @javax.persistence.PostPersist
@javax.persistence.PostLoad @javax.persistence.PreUpdate
@javax.persistence.PostUpdate @javax.persistence.PreRemove
@javax.persistence.PostRemove
@javax.persistence.PrePersist @javax.persistence.PostPersist
@javax.persistence.PostLoad @javax.persistence.PreUpdate
@javax.persistence.PostUpdate @javax.persistence.PreRemove
@javax.persistence.PostRemove
Entity Callbacks Place callbacks ...
public Customer() { } // mandatory
// getters and setters
public Customer() { } // mandatory
// getters and setters
Entity Listener Place callbacks ...
@PostUpdate void myPostUpdate(final Object o) { Customer c =
(Customer) o; System.out.println(c.toString());
} }
@PostUpdate void myPostUpdate(final Object o) { Customer c =
(Customer) o; System.out.println(c.toString());
} }
... }
... }
Interceptors ... For cross cutting with session and message-driven
b eans
allow you to encapsulate common behavior that cuts across large
parts of your application
common code that you don’t want polluting your busi ness
logic
@Stateless public class MyEjb implements MyEjbLocal {
private String name; public String getName() { return name; }
public void setName(String name) { this.name = name ; } public
MyEjb() { ... } @Override @Interceptors(MyInterceptor.class) public
String Hello(String message) throws Exceptio n {
return message + " from MyEjb"; }
private String name; public String getName() { return name; }
public void setName(String name) { this.name = name ; } public
MyEjb() { ... } @Override @Interceptors(MyInterceptor.class) public
String Hello(String message) throws Exceptio n {
return message + " from MyEjb"; }
... Interceptors public class MyInterceptor {
Object result = null; try {
+ target.getName() + ": " + (String)parameters[0];
context.setParameters(parameters); result =
context.proceed();
} catch (Exception e) { e.printStackTrace();
Object result = null; try {
+ target.getName() + ": " + (String)parameters[0];
context.setParameters(parameters) ; result = context.proceed()
;
} catch (Exception e) { e.printStackTrace();
Copyright ©2000-11 CRS Enterprises Ltd 218
Security
Security
Investigate how to use roles to restict who can use an EJB at the
class and method level
Copyright ©2000-11 CRS Enterprises Ltd 220
Authentication and Authorization Authorization
what resources can you access? use XML descriptors embed a
LOAD MORE