EJB 3.1 Programming - Timicoseddon-software/JEE/EJB Programming.pdf · Programming 1. Introduction...

319
Copyright ©2000-11 CRS Enterprises Ltd 1 EJB 3.1 Programming by Chris Seddon

Transcript of EJB 3.1 Programming - Timicoseddon-software/JEE/EJB Programming.pdf · Programming 1. Introduction...

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