Kaster Nurmukan
Kaster Nurmukan
AGENDA About Me About Java Why J2ee Coming to world ? J2ee vs .Net & Open source framework J2ee Architecture What is the usfull ?
ABOUT ME
Intraduction [email protected] Office: EN-block, 4th floor , . 10 years software Engineer (Before). Java/J2ee, C# , php , UML , JAVASCRIPT,VB etc ERP , Software Outsoursing , Campus Management system . Bank's Financial System development . China ,TianJin, Beijing ,ShenZhen
JAVA LANGUE FEATURE JVM(JAVA Virtual Machine ) Platform independent “Write Once Run Everywhere ” features Microsoft learned form Java Developed .Net and CLR(common
Language Runtime) Pure OOP Language Widely used by in business and accepted by developer
Free Runtime(JVM is free) free Development kit a lot of free java tools support Widely usage area
WHAT CAN DO WITH JAVA JavaSE JavaME JavaEE JavaFX JavaCard
WHY J2EE COMING TO WORLD History of the Programing Langues & tools C/S Desktop Appliction , Hard to maintain B/S Web Application
CGI less performance , bottleneck Scripting Language : php ,Asp
People Challenging the productivity of the tools and Method
Design Architecture : multi Layer , Most popular is MVC Possible to improve the performance in separate layer
DB layer , connection Pool , some resource Cluster : web application , business application Server
OPEN SOURCE PROJECT IN JAVA MVC framework in Java struts, Spring: J2ee open source framework Hibernate: OR-Map Framework Junit : Open Source Testing Tools in Java : Log4J :Open Source Logging Tools JFreeChart: Open Source Charting & Reporting Tools in
Java Eclipse: Open Source IDEs in Java
J2EE It is standard : API Standard jdbc , RMI , Email ,JMS ,
webservice API , Also include component standard : serverlet , EJB,
Connector , JSP (java service page ) , webservice
J2EE ARCHINECTURE
J2EE ARCHINECTURE
ALL PUT THOGETHER UNDERSTANDING THE JAVA TECHNICAL MARKET IN THE WORLD
ADEVANTAGE For big project ( at last more then 10 people/Month) , Performance(because Architecture multi tier layer, every layer memory
can be cache , can be separate to deferent platform , example : web application server , EJB Container ,
Database connection pool and database , can separate rule let the specialist easy to involve,
REFERENCE
http://www.georgehernandez.com/h/xComputers/Programming/Languages.asp
http://www.oracle.com http://www.fullstackdevelopment.com
Q&A
Topic : Servlet & JSP Kaster Nurmukan
J2EE It is standard : API Standard jdbc , RMI , Email ,JMS ,
webservice API , Also include component standard : serverlet , EJB,
Connector , JSP (java service page ) , webservice
J2EE ARCHINECTURE
SERVELET Java Servlets/JSP are part of the Sun’s J2EE Enterprise
Architecture The web development part Request controller , Filter , Adeppter Javax.Servelt
Process or store data that was submitted from an HTML form
Provide dynamic content such as the results of a database query
Manage state information Latest Servlet Spec is 3.0 (JSR 315 )
JSP Java Server Pages (JSP)
A simplified, fast way to create dynamic web content HTML or XML pages with embedded Java Code or Java Beans Can be a mix of template data in HTML/XML with some
dynamic content A JSP is a complied to a Java Servlet automatically by the
Servlet container, it is then cached Latest JSP Spec is 2.2 (JSR 245)
LIFE CYCLE OF SERVLET
init(ServletConfig); service(ServletRequest, ServletResponse);
destroy();
servlet
GenericServlet HttpServlet
doGet(HttpServletRequest, HttpServletResponse);
doPost(HttpServletRequest, HttpServletResponse); …….
EXAMPLE OF SERVLET package kz.edu; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Servlet extends HttpServlet { public init(ServletConfig) throws IOException, ServletException { //...... To do } public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<html><head><title>Sample Servlet"); out.println("</title></head><body>"); out.println("<h1>Hello World at " + req.getRequestURI() + " !</h1>"); out.println(”<p>Key is " + req.getParameter("KEY")); out.println(”</p></body></html>"); } }
USING SERVLET A catalog of servlet methods:
init(config) service(req, res)
doGet(req, res) doPut(req, res) doDelete(req, res) Destry()…
A catalog of request methods: getParameter(name) getParameterNames(), getParameterValues(name) getCookies()
A catalog of response methods: sendRedirect(url), sendError(errCode, errStr) setContentType(mimeType) addCookie(cookieObj)
J2EE WEB APPLICATION COMPONENTS Java Servlets
Extend off of HttpServlet
JSP pages, normally for Presentation Java Beans
Normally used as value objects, pass to data to JSPs
Tag Libraries – XML based JSP elements Web Deployment Descriptor
/web-inf/web.xml
May 13th, 2003
WEB DEPLOYMENT DESCRIPTOR /web-inf/web.xml
Part of the standard Defines servlets used in the web application Maps servlets to URLs A servlet can map to many URLs
Defines resources available to the web app Defines security constraints Defines other stuff like
Welcome file list Session timeout Error page mapping
May 13th, 2003
J2EE WEB DIRECTORY STRUCTURE 1 Top Directory is normally the context Path
/tomcat/webapps/testServlet Normally, the URL would be http://localhost:8080/testServlet Contains JSP and other static content plus the web-inf directory
/web-inf directory This is a protected directory, can not point browser to any file in this
directory /classes – unpacked web application classes, auto-magically
added to CLASS_PATH /lib – web application JAR files /taglib – tag library descriptor files
May 13th, 2003
J2EE WEB DIRECTORY /web-inf/web.xml /web-inf/*
Would normally put any static or JSP files here Protects them from Direct Invocation Always best to call a JSP through a servlet first
May 13th, 2003
JSP CONSTRUCTS Used in JSP pages, pages that end *.jsp Comment <%-- Comment --%> Declaration <%! int x = 0; %> Expression <%= expression %>
Outputs to the Response stream Like a “printf” to the browser Do NOT use semi-colon to terminate the line
Scriplets - contains Java Code <% code fragments %>
May 13th, 2003
JSP CONSTRUCTS
<% if (value.getName().length != 0) { %> <H2>The value is: <%= value.getName() %></H2> <% } else { %> <H2>Value is empty</H2> <% } %>
Implicit objects always available in the JSP Page “request” – Browser’s Request Object
Use to get HTTP headers, length etc.. “response” - HttpResponse Object
May 13th, 2003
JSP CONSTRUCTS “session” – internal HttpSession Object “pageContext” “application” “out”, same as <%= %> “config” – servlet configuration “page” “exception”
JSP Directives Are messages or instructions to the JSP container
May 13th, 2003
JSP CONSTRUCTS Do not produce any output “page” directive
<%@ page import=“com.lucek.*” %> Commonly used for importing class paths
“include” directive <%@ include file=“header.htm” %> Good for including static content
“taglib” – lists the tag library descriptor location Required when using tab libraries
May 13th, 2003
JAVA BEANS AS USED IN WEB APPS Normally used for all data transfers and business
components Similar to how Java Beans are used in Swing and AWT
But do not need the full implementation
Must have no constructor or no-arg constructor Must have setter and getter methods for each property
value JSP constructs/tags use Java Beans
May 13th, 2003
JSP ACTIONS JSP actions are special tags that affect the output stream
and are normally used with Java beans Most commonly used:
<jsp:useBean>, <jsp:getProperty>, <jsp:setProperty> The code below will display the lastName property of the student bean
on the output stream <jsp:useBean id="student" scope="request"
class="com.lucek.dto.StudentValue" /> <jsp:getProperty name="student" property="lastName" />
May 13th, 2003
SERVLET CONTAINER/ENGINE Servlets/JSP require a Container Apache Tomcat is the reference implementation of the
Servlet/JSP Specs It is open source, small, install quickly,and is FREE Web Site: jakarta.apache.org/tomcat It include a simple HTTP 1.1 server, good enough for
development and small intranets. Other Servlet Engine
GlassFish IBM WebSphere Application Server Jetty (web server)
May 13th, 2003
TOMCAT INSTALL Requires a JDK, get lates verstion and install into c:\jdk or
$HOME/jdk Add JAVA_HOME to your environment and the “bin”
directory to your PATH Good practice to unpack into c:\tomcat or $HOME/tomcat Add CATALINA_HOME to your environment and the “bin”
directory to your PATH
May 13th, 2003
TOMCAT DIRECTORY STRUCTURE Everything is relative to $CATALINA_HOME /bin – Startup/shutdown scripts /conf
Server.xml – main configuration file /common – common class and jar files used by Tomcat
and web applications Put JDBC drivers here
/server – class and jar files used by Tomcat internally /shared – class and jar files for all web applications /webapps – This is where you put your web application in
a sub-directory or external context file.
May 13th, 2003
STARTING TOMCAT /bin/startup.bat or startup.sh Point Browers to http://localhost:8080, should see default
page All the Docs are there on the default page! Check out the examples pages, good tutorials
May 13th, 2003
OTHER DEVELOPMENT TOOLS 1 Ant Build Tool
Standard Java Build tool Basic on UNIX make, but much better download: http://ant.apache.org
Java IDE Try NetBeans, it is nice Tomcat is built in, but is an older version Includes full Servlet and JSP debugging download: www.netbeans.org
May 13th, 2003
OTHER DEVELOPMENT TOOLS 2 Junit
Standard Automated Unit Testing Tool Site: http://junit.sourceforge.net
Jedit Slick Programmer’s Editor Written in Java Site: jedit.org
May 13th, 2003
BEST PRACTICES/PATTERNS Always Separate out the logic from the presentation
Use servlets for the logic/controller and JSP’s for presentation Ideally should never have Java Code in the JSP page
Have a clean separation between your data access and controller layers (DAO)
Always use DTO or value object Use a Model-View-Controller Architecture
Do not write it, use Struts Site: jakarta.apache.org/struts/
Use Unit tests Junit Automation via Ant build tasks
May 13th, 2003
WHAT WE HAVE NOT TALKED ABOUT All the specific Servlet APIs Tag libraries Sessions, cookies JDBC service support from the container Container based authentication Lots of other stuff
May 13th, 2003
NEXT PRESENTATION? Create a data driven web site using MySql and
Servlets/JSP Setup Authentication Realm with declarative security Setup JDBC connection pooling Struts?
May 13th, 2003
REFERENCE http://www.oracle.com
Q&A
Topic : JSF Kaster Nurmukan
AGENDA Overview of JSF Why JSF? JSF Features often case in web app JSF Life Cycle JSP vs Struts Vs JavaServer Faces
JAVASERVER FACES (JSF) is a “server side user interface component framework for Java™
technology-based web applications” is a specification and reference implementation for a web
application development framework Components Events Validators Back-end-data integration
is designed to be leveraged by tools NetBeans, RAD (Rational Application Developer), Eclipse,
JDeveloper, etc.
WHY JSF? MVC for web applications Easy to use Extensible Component and Rendering architecture Support for client device independence Standard Huge vendor and industry support Built-in UI component model (unlike JSP and Servlet)
JAVASERVER FACES – FEATURES
Page navigation specification
Standard user interface components like input fields, buttons, and links etc
Type conversion
User input validation
Easy error handling
Java bean management
Event handling
Internationalization support
PAGE NAVIGATION SPECIFICATION
JSF offers page navigation through page navigation rules in the Application Configuration file(faces-config.xml)
Page Navigation can be
Simple Page Navigation
Conditional Page Navigation
Simple page navigation <navigation-rule>
<from-tree-id>/page1.jsp</from-tree-id> <navigation-case> <to-tree-id>/page2.jsp</to-tree-id> </navigation-case> </navigation-rule>
Conditional Page Navigation <navigation-rule>
<from-tree-id>/login.jsp</from-tree-id> <navigation-case> <from-outcome>success</from-outcome> <to-tree-id>/welcome.jsp</to-tree-id>
</navigation-case> </navigation-case > </navigation-rule>
HOW NAVIGATION IS DONE When a button or hyperlink is clicked the component associated with it generates an
action event.
This event is handled by the default ActionListener instance, which calls the action method referenced by the component that triggered the event.
This action method is located in backing bean and is provided by application developer.
This action method returns a logical outcome String which describes the result of the processing.
The listener passes the outcome and a reference to the action method that produced the outcome to the default NavigationHandler.
The NavigationHandler selects the next page to be displayed by matching the outcome or the action method reference against the navigation rules in the application configuration resource file.
USER INPUT VALIDATION
If validation or type conversion is unsuccessful, a component specific FacesMessage instance is added to FacesContext. The message contains summary, detail and severity information
Validation can also be delegated to a
managed bean by adding a method binding in the validator attribute of an input tag.
This mechanism is particularly useful for
accomplishing form validation, where combinations of inputted values need to be evaluated to determine whether validation should succeed.
Standard/Built-in validation components <h:inputText id="age" value="#{UserRegistration.user.age}"> <f:validateLongRange maximum="150" minimum="0"/> </h:inputText>
Custom Component public class CodeValidator implements Validator{ public void validate(FacesContext context, UIComponent
component, Object value) throws ValidatorException
{ } } <validator> <validator-id>jcoe.codeValidator</validator-id> <validator-
class>com.jcoe.validation.CodeValidator</validator-class>
</validator> <h:inputText id="zipCode"
value="#{UserRegistration.user.zipCode}" <f:validator validatorId="jcoe.codeValidator"/> </h:inputText>
FEW IMPORTANT UI COMPONENTS
Few important UI components are:
UIForm: Encapsulates a group of controls that submit data to the application. This
component is analogous to the form tag in HTML. UIInput: Takes data input from a user. This class is a subclass of UIOutput
UICommand: Represents a control that fires actions when activated.
UIOutput: Displays data output on a page.
UIMessage: Displays a localized message.
STANDARD UI COMPONENTS
To use the HTML and Core custom tag libraries in a JSP page, you must include the taglib directives in the page.
The components are reusable
Taglib directives <%@ taglib uri="http://java.sun.com/jsf/html/"
prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core/"
prefix="f" %>
Components <h:commandButton id="submit" action=“next"
value="Submit" /> <h:inputText id="userName"
value="#{GetStudent.userName}" required="true" >
<h:outputText value="#{Message.greeting_text}" />
TYPE CONVERSION
A JavaServer Faces application can optionally associate a component with server-side object data. This object is a JavaBeans component. An application gets and sets the object data for a component by calling the appropriate object properties for that component.
When a component is bound to an object, the application has two views of the component's data:
The model view, in which data is represented as data types, such as int or long.
The presentation view, in which data is represented in a manner that can be read or modified by the user. For example, a java.util.Date might be represented as a text string in the format mm/dd/yy or as a set of three text strings.
HOW CONVERSION IS DONE?
The JSF technology automatically converts the
component data between the model view and the presentation view.
You can create your own custom converter. To create a custom converter converter in your
application,three things must be done: 1. The application developer must
implement the Converter class. 2. The application architect must
register the Converter with the application.
3. The page author must refer to the Converter from the tag of the component whose data must be converted
The converter attribute on the component tag
<h:inputText value="#{student.Age}"
converter="javax.faces.convert.IntegerConverter" />
The method to convert the model value of the component
Integer age = 0; public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; }
ERROR HANDLING
The JSF core component set provide an HtmlMessages component, which simply outputs the summary message from all the FacesMessage instances added to the FacesContext during validation
Depending on the severity and type of error, the response to it may vary, but at least a sensible error message usually should be shown to the end user.
The JSF framework has several points within its page request processing lifecycle that can raise errors and display consistent error messages.
JAVA BEAN MANAGEMENT
The managed-bean element in the faces-
config.xml application configuration file manages the java beans.
Each managed-bean element registers a JavaBean that JSF will instantiate and store in the specified scope.
Faces-config.xml <!ELEMENT managed-bean
(description*, display-name*, icon*, managed-bean name, managed-bean-class, managed-bean-scope, (managed-property* | map-
entries | list-entries ))>
EVENT HANDLING JSF applications are event-driven. Handling events in JSF is surprisingly easy. Here are the
steps:
Write an event listener.
Deploy the event listener in the WEB-INF/classes or WEB-INF/lib directory under the application directory.
In the tag representing the component whose event is to be captured, use an action_listener or a valuechange_listener tag defined in the Core custom tag library.
Event objects
Must extend javax.faces .event.FacesEvent
FacesEvent is a subclass of the java.util.EventObject class
It adds the getComponent method, which returns the UIComponent component that fired the event.
The FacesEvent class has two subclasses: ActionEvent and ValueChangeEvent.
The ActionEvent class represents the activation of the UI component, such as a UICommand component.
The ValueChangeEvent class represents a notification that the local value of a UIInput component has been changed.
EVENT HANDLING (CONT.)
Event listeners
javax.faces.event.FacesListener interface
This interface extends the java.util.EventListener interface
The FacesListener interface has two subinterfaces: ActionListener and ValueChangeListener
OFTEN CASE IN WEB APP
1. Output dynamic text • Render data to the screen
2. Loop structures • Output collection or render tables
3. Optional rendering of components • Render some components based on state
4. Trigger Actions • User actions or data transmission
61
OUTPUT DYNAMIC TEXT
Uses the h:outputText tag Also h:outputLabel and h:outputFormat
Uses Expression Language Requires a bean
Defined in the faces-config or the template
Can set style and turn on/off escaping
62
<h:outputText value="#{JsfAppBean.currentItem.title}"/>
<h:outputText value="#{msgs.jsfapp_text}"/>
LOOP STRUCTURE
h:dataTable is the main loop structure Also h:panelGrid to a degree
Takes a collection as value Uses a variable (entry) to interact with collection
Uses h:column to define each column
63
<h:dataTable id="itemlist” value="#{JsfAppBean.allItems}” var="entry"> <h:column> <f:facet name="header"> <h:outputText value="#{msgs.jsfapp_text}"/> </f:facet> <h:outputText value="#{entry.item.title}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="#{msgs.jsfapp_hidden}"/> </f:facet> <h:selectBooleanCheckbox id="itemHidden" value="#{entry.item.hidden}" disabled="true" /> </h:column> </h:dataTable>
OPTIONAL RENDERING
Handled per h: tag with the rendered attribute (which takes EL) Can prefix with not to invert
Brings render logic into the template
64
<h:outputText value="#{entry.item.title}" rendered="#{not entry.canDelete}"/>
<h:commandLink id="updatelink" action="#{JsfAppBean.processActionUpdate}" rendered="#{entry.canDelete}"> <h:outputText value="#{entry.item.title}"/> </h:commandLink>
JSF LIFE CYCLE
MVC ARCHITECTURE IN JSF
JSP VS STRUTS VS JAVASERVER FACES JSF JSP JSP and Struts
Components Rich UI-data-bound components with events provided Custom components
Standard tags (JSTL) that are non-UI and very basic Custom components through tag libraries
Struts-specific tag library Only very basic, form-bean-bound components provided
Device independence Reader kits that provide device independence
None
None
Error handling and validation
Validation framework Many predefined validators
None Validation framework driven by an XML file (validation.xml)
Scripting
Scripts can be attached to events All components accessible from scripts
Embedded Java™ in the page
Scripts written in Java Action classes Form data but not components accessible
Page flow Simple navigation file (faces-config.xml)
None Sophisticated, flexible framework XML file based
Session and object management
Automatic Manual Manual
Q&A
Topic : Hibernate 1 Kaster Nurmukan
HIBERNATE An ORM tool Used in data layer of applications Implements JPA
THE PROBLEM BEFORE THEN HIBERNATE id Name Age birthday
Id Name Age
Brithday
THE PROBLEM Mapping object variables to column Mapping relationship Inheritance : java have , RDBMS no. Associations :in java Reference ; in RBDMS foreign key Handling data Type Managing changes to object state
ORM What is ORM
ORM stands for Object-Relational Mapping (ORM) is a programming technique for converting data between relational databases and object oriented programming languages such as Java, C# etc
Advantages Lets business code access objects rather than DB tables. Hides details of SQL queries from OO logic No need deal with database implementation Entities based on business concept s rather then database structure Transaction management and automatic key generation Fast development of application
JAVA ORM FRAMEWORKS
Enterprise JavaBeans Entity Beans Java Data Object Castor TopLink Spring DAO Hibernate More
HIBERNATE Hibernate is an Object-Relational Mapping(ORM) solution for JAVA and it
raised as an open source persistent framework created by Gavin King in 2001. It is a powerful, high performance Object-Relational Persistence and Query service for any Java Application
NHibernate for .Net. opensource
HIBERNATE FEATURES O-R mapping using ordinary JavaBeans
Can set attributes using private fields or private setter methods
Lazy instantiation of collections (configurable)
Polymorphic queries, object-oriented query language
Cascading persist & retrieve for associations, including collections and many-to-many
Transaction management with rollback
Can integrate with other container-provided services
LEARN HIBERNATE WHAT YOU NEED Study path ,If JDBC way :
SQL Fundamentals
JDBC Fundamentals
Design and Code
IF use a framework
How to use Hibernate Configure a Database
IF use a stardard How to use JPA Configure a Database
APPLICATION ARCHITECTURE
User Interface
Application Logic
business Objects DAO
Hibernate
JDBC Foundation Classes
UI event
data request
Hibernate API business object
business object
Data object
JDBC API ResultSet, etc.
hibernate.cfg.xml
*.hbm.xml class mappings
SessionFactory
HIBERNATE.CFG.XML FOR MYSQL
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC ... remainder omitted > <hibernate-configuration> <session-factory> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="connection.username">student</property> <property name="connection.password">pw</property> <property name="connection.url"> jdbc:mysql://localhost:3306/dbtest</property> <!-- Object-Relational mappings for classes --> <mapping resource="eventmgr/domain/Location.hbm.xml"/> ... other mappings omitted </session-factory> </hibernate-configuration>
HIBERNATE IN APPLICATION ARCHINECTURE
Source: Hibernate Reference Manual (online)
HIBERNATE BASICS
Session A single-threaded, short-lived object representing a conversation between the application and the persistent store. Wraps a JDBC connection. Factory for Transaction. Holds a mandatory (first-level) cache of persistent objects, used when navigating the object graph or looking up objects by identifier.
HIBERNATE BASICS
Persistent Objects and Collections Short-lived, single threaded objects containing persistent state and business function. These might be ordinary JavaBeans/POJOs, the only special thing about them is that they are currently associated with (exactly one) Session. As soon as the Session is closed, they will be detached and free to use in any application layer (e.g. directly as data transfer objects to and from presentation).
HIBERNATE BASICS
Transient Objects and Collections Instances of persistent classes that are not currently associated with a Session. They may have been instantiated by the application and not (yet) persisted or they may have been instantiated by a closed Session.
HIBERNATE BASICS
Transaction (Optional) A single-threaded, short-lived object used by the application to specify atomic units of work. Abstracts application from underlying JDBC, JTA or CORBA transaction. Multiple transactions per Session.
HIBERNATE BASICS
ConnectionProvider (Optional) A factory for (and pool of) JDBC connections. Abstracts application from underlying Datasource or DriverManager. Not exposed to application, but can be extended/implemented by the developer. TransactionFactory (Optional) A factory for Transaction instances. Not exposed to the application, but can be extended/implemented by the developer.
SESSIONFACTRY try { configuration.configure(configFile); sessionFactory =
configuration.buildSessionFactory(); } catch (Exception e) { System.err .println("%%%% Error Creating SessionFactory
%%%%"); e.printStackTrace(); }
SESSION
public Session getSession() { return HibernateSessionFactory.getSession(); }
SAVE TO DB WITH HIBERNATE public void save(Answer answer) { log.debug("saving Answer instance"); try { getSession().save(answer); log.debug("save successful"); } catch (RuntimeException re) { log.error("save failed", re); throw re; } }
TAKE CARE WITH TRANSACTION private UserDAO uDao = new UserDAO(); …….. try { Transaction trans= uDao.getSession().beginTransaction(); trans.begin(); uDao.save(user); trans.commit(); } catch (RuntimeException e) { throw e; }
REFERENCE http://www.oracle.com
Q&A
Topic : Hibernate 2: Object Persistence and ORM Kaster Nurmukan
AGENDA Overview of table relashionship with Object Goal & Purpose Analyzing An Example
OBJECT-RELATIONAL MAPPING Purpose save object as a row in a database table create object using data from table save and create associations between objects Design Goals separate O-R mapping service from our application localize the impact of change in database
Java Application
object
Persistent Storage
AN EXAMPLE An Seminar Topic Manager application with these classes:
OBJECT-RELATIONAL MAPPING Map between an object and a row in a database table.
LOCATIONS PK id INTEGER name VARCHAR(80) address VARCHAR(160)
Location id: int name: String address: String
Class should have an identifier attribute
Database Table identifier is usually the primary key of table
Object Mapper
Object Mapper convert object to table row data, convert data types, instantiates objects
MAPPING AN OBJECT
LOCATIONS id name address 01 SDU University Ablaihan ... 02 Seacon Square 120 street ...
ku : Location id = 01 name = “SDU University" address = “Ablaihan ..."
object diagram
save( )
O-R MAPPING CODE FOR LOCATION (1) Location loca = new Location( “SDU University" ); loca.setAddress( “No xx ablaihan Road" );
// save the location objectMapper.save(loca );
Issues:
• mapper should choose a unique ID for saved objects
• what happens if same data is already in the table?
FINDING AN OBJECT
// retrieve the location
Location localtion1 = objectMapper.find(“SDU University"); Location localtion1 = objectMapper.find(“SDU University");
what field does find( ) search for? id field? name field?
does mapper always return the same object?
(localtion1 == localtion2 ) => true or false?
FINDING AN OBJECT: SOLUTION
// retrieve the location Location sdu = objectMapper.find( 111 ); List sdu_list = objectMapper.query( "'SELECT WHERE name LIKE ‘SDU U%'");
Provide two kinds of "find".
find( key ) - find object by primary key
query( string ) - find objects using a flexible query language. May return many matches.
TRANSPARENT PERSISTENCE
Location sdu= new Location( “SDU University" ); sdu.setAddress( “xx ablaihan, … " ); // save the location objectMapper.save(sdu ); // change the address sdu.setAddress( “doctikh, xxxx" );
With transparent persistence, changes to a "managed" object are automatically propagated to the database.
LOCATIONS id name address 01 Sdu University xxx... 02 dd 120 strate...
O-R MAPPING OF N-TO-1 ASSOCIATIONS Seminar
id: int name: String startDate: Date location: Location …..
Location id: int name: String address: String
1 *
O-R MAPPING OF N-TO-1 ASSOCIATIONS Seminar
id: int name: String startDate: Date location: Location
LOCATIONS PK id INTEGER name VARCHAR address VARCHAR
Location id: int name: String address: String
Seminar PK id INTEGER name VARCHAR start_date TIMESTAMP FK location_id INTEGER
The ORM converts a n-to-1 association to a foreign key relation (persist) or foreign key to object (retrieve).
1 *
CASCADED SAVE
Seminar siminar = new Seminar( "JavaEE Days" ); Location lo = new Location( “SDU University" ); lo.setAddress( “xx Ablaihan; kaskelen" ); siminar.setLocation( ku ); siminar.setStartDate( new Date(11,Calendar.JULY, 1) ); // save the event objectMapper.save(siminar);
When we save the siminar, does it save the location, too?
Is this done automatically?
Save an Seminar...
DELETING AN SIMINAR
// delete the siminar Siminar siminar = objectMapper.find( "JavaEE Days" ); objectMapper.delete(siminar);
Does the dataMapper delete the Location, too?
What if other Siminars (in database) still refer to this Location?
FETCHING AN SIMINAR
// retrieve the siminar Siminar siminar = objectMapper.find( "JavaEE Days" ); Location location = room.getLocation( ); // null?
When we get the siminar , does the ORM fetch the location, too?
O-R MAPPING OF 1-TO-N ASSOCIATIONS Seminar
id: int name: String startDate: Date
Speaker id: int name: String telephone: String
speakers
*
O-R MAPPING OF 1-TO-N ASSOCIATIONS Seminar
id: int name: String startDate: Date
SPEAKERS PK id INTEGER name VARCHAR telephone VARCHAR FK event_id INTEGER
Speaker id: int name: String telephone: String
Seminar PK id INTEGER name VARCHAR start_date TIMESTAMP FK location id INT
Siminar has a collection of Speakers. The ORM saves a collection as Speaker entries with FK reference to Event.
speakers
*
O-R MAPPING FOR COLLECTIONS (1) Siminar siminar = new Siminar ( "JavaEE Days" ); siminar.setLocation( location ); // add siminar speakers Speaker jhon= new Speaker( “Jhon Simith" ); Speaker hans = new Speaker( "Prof. K" ); siminar.getSpeakers().add( jhon); siminar.getSpeakers().add( hans); // save the siminar objectMapper.save( siminar);
Issues:
• same issues as many-to-1 association
HOW TO MAP COLLECTIONS?
// retrieve the room Siminar siminar= objectMapper.find("JavaEE Days"); Collection speakers = siminar.getSpeakers( );
What kind of collection does ORM return?
Can we use any collection we want?
List?
ArrayList?
O-R MAPPING OF ORDERED COLLECTIONS Siminar
id: int name: String startDate: Date
Speaker id: int name: String telephone: String
speakers {ordered}*
O-R MAPPING OF ORDERED COLLECTIONS Siminar
id: int name: String startDate: Date
SPEAKERS PK id INTEGER name VARCHAR FK event_id INTEGER speaker_idx INT
Speaker id: int name: String
Siminar PK id INTEGER name VARCHAR start_date TIMESTAMP FK location_id INT
Siminar has a list or array of Speakers. The ORM must store a foreign key and a list index in the Speaker table.
sessions {ordered}*
O-R MAPPING OF M-TO-N ASSOCIATIONS Siminar
id: int name: String startDate: Date
Attendee id: int name: String telephone: String
attendees *
Siminar *
O-R MAPPING OF M-TO-N ASSOCIATIONS Seminar
id: int name: String startDate: Date
ATTENDEES PK id INTEGER name VARCHAR telephone VARCHAR
Attendee id: int name: String telephone: String
Seminar PK id INTEGER name VARCHAR start_date TIMESTAMP FK location_id INT
attendees *
Siminar *
SIMINAR_ATTENDEE PK id INTEGER FK siminar_id INTEGER FK attendee_id INTEGER
WHAT IS CASCADING?
When you save/update/delete an object in database... are associated objects also saved/updated/deleted?
e: SIMINAR
Attendee
attendees {set}
SIMINAR table
ATTENDEES table
save( e )
?
FRAMEWORKS PROVIDE CASCADING
In JPA, using annotations:
@Entity class Siminar { @OneToMany(mappedBy=“siminar", cascade=PERSIST) private List<Person> attendees;
NONE PERSIST REFRESH REMOVE ALL
CASCADING IN HIBERNATE
In Hibernate mapping file for Siminar:
<class name=“Siminar" table=“SIMINAR" lazy="false"> <id name="id" column="ID"> </id> <property name="name" column="Name"/> <set name="attendees" cascade="save-update"> <key column=“siminar_id"/> <one-to-many class="Person"/> </set>
cascade= "none" don't cascade operations "all" cascade all operations (be careful) "save-update" cascade save and updates "delete-orphan" cascade all, delete unreferenced orphan children
WHAT ARE EAGER AND LAZY FETCHING?
When you create an object from database... when are associated objects created? e: Room
Attendee
attendees {set}
Rooms table
ATTENDEE table
find( id )
?
WHY IS FETCHING IMPORTANT?
Example: get a Country from Country database. Country kz= orm.query( "SELECT c FROM Country c WHERE c.name=‘Kazakhstan'"); System.out.println( "Population is "+kz.getPopulation() );
Country cities: Set City
has 90 cities
How many objects are created? a) One - just the Country object
b) 91 - Country + all 90 cities
WHAT ARE EAGER AND LAZY FETCHING?
Eager: create all associated object immediately. Lazy: create associated objects only when they are
referenced.
Country kz = orm.query("SELECT c FROM ..."); System.out.println( "Population is "+kz.getPopulation() ); for(City c: kz.getCities() ) Sytem.out.println("has city: "+city);
EAGER
LAZY
PROBLEM WITH LAZY FETCHING
The query or connection object might be closed before the code accesses the cities.
// This code uses JPA em = entityManagerFactory.getEntityManager(); Query q = em.createQuery("SELECT c FROM ..."); Country kz = q.getSingleResult(); // close entity manager to free resources em.close( ); for(City c: kz.getCities() ) Sytem.out.println("has city: "+city);
ERROR: not attached to database
DESIGN MODEL FOR OBJECT MAPPER Object Mapper
find( id ) : T
query( query : String ): T[*]
findAll( ) : T[*]
save( object : T )
update( object : T )
delete( object : T )
T
A UML Type Parameter
The method to "find" an Object by its identifier maybe named:
load( id ) the Hibernate and Spring name
find( id, Class ) JPA
get( id ) similar to load but no exception if id is not found
OBJECT-RELATIONAL OPERATIONS: CRUD Common O-R operations are:
Create - save (persist) a new object in the database
Retrieve an object from the database
Update data for an object already saved in database
Delete object data from the database
OBJECT MAPPING FOR EVENT CLASS This class is generally called a
Data Access Object (DAO). Hibernate uses the term "data access object". Append "Dao" to the class name, e.g. EventDao.
EventDao
find( id: int ) : Event
query( query: String ) : Event[*]
save( evt: Event )
update( evt: Event )
delete( evt: Event )
LAYERED DESIGN
User Interface
Application Logic
Domain Objects DAO
O-R Mapping Framework Other Services
JDBC Foundation Classes
ui event
CRUD request
ORM API domain object
domain object
data xfer object
JDBC API ResultSet, etc.
WHEN NOT TO USE O-R MAPPING
In some applications, Object-Relational mapping is inefficient. Example: display a table of attendees
Name Telephone Email
Bill Gates 1-215-555-1212 [email protected]
B. Obama 1-212-111-1212 president@whitehouse
PersonDao
TableModel
RowSet
Person objects
4 APPROACHES TO ORM
1. No ORM -- JDBC in my code. No Layers! Put the JDBC right in your app code. 2. Do It Myself. Write your own DAO using JDBC. 3. Use a Framework. Hibernate, MyBatis, TopLink, or other. 4. Use a Standard. Java Persistence Architecture (JPA) or Java Data
Objects (JDO) provide a standard API that have many implementations.
PERSISTENCE FRAMEWORKS Hibernate - most popular open-source persistence
framework for Java. NHibernate for .Net. Uses POJOs and object-query language. Completely
decouple Java from database. Can reverse engineer.
MyBatis - simple, uses SQL maps. Database schema not transparent to Java code.
Cayenne - Apache project, has GUI modeler that eliminates need to write xml. Can reverse engineer database or generate database schema & Java code.
TopLink (Oracle) Torque (Apache DB) Castor, ...
PERSISTENCE STANDARDS Java Persistence API (JPA)
standard for persistence of plain java objects. Can be used with stand-alone or enterprise apps. Good IDE support. EclipseLink, TopLink Essentials (Glassfish project), OpenJPA.
DataNucleus, Hibernate Annotations.
Java Data Objects (JDO) transparent persistence of POJOs; can persist to LDAP, RDBMS, Excel, and other Kodo, DataNucleus
REFERENCE FOR FRAMEWORKS
Article: Adopting a Java Persistence Framework, http://today.java.net/pub/a/today/2007/12/18/adopting-java-persistence-framework.html
NO PERSISTENCE FRAMEWORK
Web4J (www.web4j.org) web + database in Java without O-R mapping. Interesting
& educational web site Presents arguments why not to use a framework (but
doesn't mention Hibernate).
REFERENCE http://www.hibernate.org/hib_docs/reference/en/html_single/ http://www.hibernate.org/78.html
http://www.oracle.com
Q&A
Topic : Hibernate 3:Advanced ORM Kaster Nurmukan
AGENDA Advanced ORM Embedded class Collections Inheritance &Practice
BASIC OBJECT-RELATIONAL MAPPING
Class-level annotations @Entity and @Table
Id field @Id and @GeneratedValue
Fields of simple types @Basic (can be omitted) and @Column
Fields of class types @ManyToOne and @OneToOne
ADVANCED ORM Embedded class Collections Inheritance
EMBEDDED CLASS
public class Address { String street; String city; String state; String zip; }
users
id … street city state zip …
public class User { Integer id; String username String password; Address address; }
MAPPING EMBEDDED CLASS
@Embeddable public class Address { String street; String city; String state; String zip; }
@Entity public class User { @Id Integer id; String username String password; @Embedded Address address; }
COLLECTION OF SIMPLE TYPES
public class Customer { Integer id; String name; String address; Set<String> phones; }
MAPPING ELEMENT COLLECTION
id
customers Customer_phones
Customer_id phones
@ElementCollection Set<String> phones;
CUSTOMIZE COLLECTION TABLE
@ElementCollection @CollectionTable( name = “customer_phones”, joinColumns=@JoinColumn(name = “customer_id”) ) @Column(name=“phone”) Set<String> phones;
LIST OF SIMPLE TYPES
Order by property @OrderBy(“<property_name> ASC|DESC”) Simple types do not have properties
Order by a separate column
@ElementCollection @OrderBy(“asc”) List<String> phones;
@ElementCollection @OrderColumn(name = “phone_order”) List<String> phones;
ISSUES RELATED TO COLLECTIONS OF OBJECT TYPES Relationships (a.k.a. associations)
one-to-many many-to-many
Unidirectional vs. Bidirectional Set and List Cascading behaviors
TYPES OF RELATIONSHIPS Many-to-Many Many-to-One / One-to-Many One-to-One
MANY-TO-MANY RELATIONSHIP Each entity in E1 can
be related to many entities in E2
Each entity in E2 can be related to many entities in E1
E1 E2
MANY-TO-ONE RELATIONSHIP Each entity in E1 can
be related to one entities in E2
Each entity in E2 can be related to many entities in E1
E1 E2
ONE-TO-ONE RELATIONSHIP Each entity in E1 can
be related to one entities in E2
Each entity in E2 can be related to one entities in E1
E1 E2
RELATIONSHIP TYPE EXAMPLES Books and authors?? Books and editors??
ONE-TO-MANY EXAMPLE A customer may own multiple accounts An account only has one owner
BIDIRECTIONAL ASSOCIATION – OO DESIGN #1
public class Account { Integer id; Double balance; Date createdOn; Customer owner; }
public class Customer { Integer id; String name; String address; Set<String> phones; Set<Account> accounts; }
UNIDIRECTIONAL ASSOCIATION – OO DESIGN #2
public class Account { Integer id; Double balance; Date createdOn; }
public class Customer { Integer id; String name; String address; Set<String> phones; Set<Account> accounts; }
UNIDIRECTIONAL ASSOCIATION – OO DESIGN #3
public class Account { Integer id; Double balance; Date createdOn; Customer owner; }
public class Customer { Integer id; String name; String address; Set<String> phones; }
UNIDIRECTIONAL VS. BIDIRECTIONAL Do the three OO designs result in different database
schemas?? Does it make any difference on the application side?? Which one should we use??
MAPPING BIDIRECTIONAL ONE-TO-MANY
public class Account { Integer id; Double balance; Date createdOn; @ManyToOne Customer owner; }
public class Customer { Integer id; String name; String address; Set<String> phones; @OneToMany(mappedBy=“owner”) Set<Account> accounts; }
property
USING LIST
public class Customer { Integer id; String name; String address; Set<String> phones; @OneToMany(mappedBy=“owner”) @OrderBy( “createdOn asc” ) List<Account> accounts; }
MANY-TO-MANY EXAMPLE A customer may own multiple accounts An account may have multiple owners
MAPPING MANY-TO-MANY
public class Account { Integer id; Double balance; Date createdOn; @ManyToMany Set<Customer> owners; }
public class Customer { Integer id; String name; String address; Set<String> phones; @ManyToMany(mappedBy=“owners”) Set<Account> accounts; }
CUSTOMIZE JOIN TABLE
@ManyToMany @JoinTable( name = “account_owners”, joinColumns=@JoinColumn(name = “account_id”), inverseJoinColumns=@JoinColumn(name=“owner_id”) ) Set<Customer> owners;
CASCADING BEHAVIOR
Whether an operation on the parent object (e.g. Customer) should be applied to the children objects in a collection (e.g. List<Account>)
Customer c = new Customer(“cysun”); Account a1 = new Account(); Account a2 = new Account(); c.getAccounts().add( a1 ); c.getAccounts().add( a2 ); entityManager.persist(c); // will a1 and a2 be saved as well? entityManager.remove(c); // will a1 and a2 be deleted from db??
CASCADING TYPES IN JPA http://sun.calstatela.edu/~cysun/documentation/jpa-2.0-
api/javax/persistence/CascadeType.html
CASCADETYPE EXAMPLES
@OneToMany(mappedBy=“owner”, cascade=CascadeType.PERSIST) List<Account> accounts;
@OneToMany(mappedBy=“owner”, cascade={CascadeType.PERSIST, CascadeType.MERGE}) List<Account> accounts;
@OneToMany(mappedBy=“owner”, cascade=CascadeType.ALL) List<Account> accounts;
INHERITANCE
public class CDAccount extends Account { Integer term; }
EVERYTHING IN ONE TABLE
id account_type balance created_on term
accounts
Discriminator column
INHERITANCE TYPE – SINGLE_TABLE
@Entity @Table(name=“accounts”) @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name=“account_type”) @DiscrimnatorValue(“CHECKING”) public class Account { … }
@Entity @DiscrimnatorValue(“CD”) public class CDAccount { … }
TABLE PER SUBCLASS
id balance created_on accounts
account_id term cd_accounts
foreign key
INHERITANCE TYPE – JOINED
@Entity @Table(name=“accounts”) @Inheritance(strategy=InheritanceType.JOINED) public class Account { … }
@Entity @Table(name=“cd_accounts”) public class CDAccount { … }
TABLE PER CONCRETE CLASS
id balance created_on
accounts
id balance created_on term
cd_accounts
INHERITANCE TYPE – TABLE_PER_CLASS
@Entity @Table(name=“accounts”) @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public class Account { … }
@Entity @Table(name=“cd_accounts”) public class CDAccount { … }
TIPS FOR HIBERNATE MAPPING Understand relational design
Know what the database schema should looks like before doing the mapping
Understand OO design Make sure the application design is object-oriented
FURTHER READINGS TopLink JPA Annotation Reference –
http://www.oracle.com/technetwork/middleware/ias/toplink-jpa-annotations-096251.html
Pro JPA 2 by Mike Keith and Merrick Schincariol
HOMEWORK Reading online resouce JPQL / Criteria http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html http://www.objectdb.com/java/jpa/query http://en.wikipedia.org/wiki/Java_Persistence_Query_Lang
uage
Q&A
Topic : JPA Kaster Nurmukan
AGENDA Overview of JPA EntityManager
AGENDA O/R Mapping Primary entity annotations EntityManager Entity Relationships Practice
O/R MAPPING
Database Table
POJO Forward Engineering
Reverse Engineering
Java Persistence API
HIBERNATE AND JPA Java Persistence API (JPA)
Annotations for object-relational mapping Data access API An object-oriented query language JPQL
Hibernate The most popular Java ORM library An implementation of JPA
HIBERNATE USAGE
Hibernate without JPA API: SessionFactory, Session, Query, Transaction
More features Hibernate with JPA
API: EntityManagerFactory, EntityManager, Query, Transaction
Better portability Behaviors are better defined and documented
A HIBERNATE EXAMPLE
Java classes Employee.java
JPA configuration file persistence.xml
Code to access the persistent objects EmployeeTest.java
(Optional) Logging configuration files log4j.properties
JAVA CLASSES Plain Java classes (POJOs); however, it is recommended
that Each persistent class has an identity field Each persistent class implements the Serializable interface Each persistent field has a pair of getter and setter, which don’t
have to be public
PRIMARY ENTITY ANNOTATIONS @Entity. Mark class as an entity @Id. Define primary key @EmbeddedId. Define composite key @Table(name=“TABLE_NAME”). Define table name for
entity class. @Column. Define column property. @Transient. Ignored by persistence framework. @GeneratedValue,@SequenceGenerator. Autopopulate
column with sequence generator.
ENTITYMANAGER Maintains a cache of instances within a transactional
context (persistence context) We can acquire EntityManager instance using : Dependency Injection EntityManagerFactory JNDI Lookup
Operations : persist(), merge(), remove(), find(), createNamedQuery(), createQuery()
Persistence unit is declared in persistence.xml
ENTITY RELATIONSHIPS @OneToOne. One to One is represented by a
single-value entity reference at one or both ends of the relationship
@OneToMany. This annotation is added to a Collection relationship field.
@ManyToOne. Indicating that is an entity is part of a Collection
@ManyToMany. This annotation is assigned to a Collection relationship field to indicate the target entity also has a Collection of the source entity type.
Lazy vs Eager Binding Cascade (ALL, PERSIST, MERGE, REMOVE,
REFRESH)
v110912 Java Persistence: EntityManager 188
JAVAX.PERSISTENCE.ENTITYMANAGER Replaces much of the EJB 2.x “Home” functionality Handles O/R Mapping of Entities to the database Provides APIs
inserting objects into database getting objects from database synchronizing objects with database querying database
Provides caching Coordinates with transactional services (JTA) Tightly integrated with Java EE and EJB, but not
limited to that environment
v110912 Java Persistence: EntityManager 189
JAVAX.PERSISTENCE.ENTITYMANAGER Replaces much of the EJB 2.x “Home” functionality Handles O/R Mapping of Entities to the database Provides APIs
inserting objects into database getting objects from database synchronizing objects with database querying database
Provides caching Coordinates with transactional services (JTA)
Tightly integrated with Java EE and EJB, but not limited to that environment
v110912 Java Persistence: EntityManager 190
ENTITIES
(formerly and sometimes still called Entity Beans) are now Plain Old Java Objects (POJOs)
nothing special happens when calling new
Author author = new Author();
are not persistent until associated with an EntityManager em.persist(author);
v110912 Java Persistence: EntityManager 191
EXAMPLE AUTHOR POJO ENTITY @javax.persistence.Entity public class Author { private long id; private long version=0; private String firstName; private String lastName; private String subject; private Date publishDate; public Author() {} public Author(long id) { this.id = id; } @Id @GeneratedValue public long getId() { return id;} private void setId(long id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } ... }
Warning: Using GeneratedValue without specifying a specific strategy should only be used when you have no intention of controlling how the provider manages primary keys for this object type. This would be rare.
v110912 Java Persistence: EntityManager 192
CREATING ENTITY IN DATABASE Author author = new Author(); //primary key will be gen author.setFirstName("dr"); author.setLastName("seuss"); author.setSubject("children"); author.setPublishDate(new Date()); log_.info("creating author:" + author); em.persist(author); log_.info("created author:" + author); //output -creating author:id=0, fn=dr, ln=seuss, subject=children, pdate=Fri Sep 15 11:54:15 EDT 2006 -created author:id=50, fn=dr, ln=seuss, subject=children, pdate=Fri Sep 15 11:54:15 EDT 2006
v110912 Java Persistence: EntityManager 193
MANAGED AND UNMANAGED ENTITIES Unmanaged state (detached)
instance not associated with an EntityManager state changes are not tracked can be serialized to client and returned to be
synchronized with database nothing equivalent to this state in EJB 2.1 entity beans
Managed state (attached) instance associated with an EntityManager state changes are tracked within a Persistence Context EJB 2.1 entity beans were always managed
client interfaced with data through a proxy or state transferred through a Data Transfer Object
v110912 Java Persistence: EntityManager 194
PERSISTENCE CONTEXT A set of attached entity instances managed by an
EntityManager All entities become detached once closed Two types
Transaction-scoped Persistence Contexts begin/end at transaction boundaries only made available through container managed persistence
contexts Extended Persistence Contexts
live beyond any single transaction allow longer-lived interactions with database without lengthy
transactions tying up database resources
195
PERSISTENCE CONTEXT EXAMPLES Transaction-scoped (inside server container)
@PersistenceContext(unitName=”jpaDemo”) EntityManager em;
@TransactionAttribute(REQUIRED) public void update(long authorId, String type) {
Author author = em.find(Author.class, authorId); author.setType(type);
}
Extended (inside or outside server container) EntityManager em = Persistence.
createEntityManagerFactory(“jpaDemo”).createEntityManager();
tx.begin(); //tx 1 begins Author author = em.find(Author.class, authorId); tx.commit(); //tx 1 ends, but author remains managed ... tx.begin(); //tx 2 begins author.setType(type); tx.commit(); //tx 2 ends, and author is still managed
until close
196
PERSISTENCE UNIT
A set of classes that are mapped to the database defined in META-INF/persistence.xml must have an identity
“” is a valid identity Classes
may be named in persistence.xml file may be automatically scanned for in the classpath
orm.xml optionally provided to augment, provide, or replace class
persistence metadata (more on orm.xml in Core ORM topic)
v110912 Java Persistence: EntityManager 197
EXAMPLE COMPONENT LAYOUT META-INF/ +---persistence.xml ejava + ---examples +---… +---DAOException.class +---AuthorDAO.class +---jpa | +---JPAAuthorDAO.class | +---JPADAOBase.class +--domain +---Author.class
198
EXAMPLE PERSISTENCE.XML <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="jpaDemo"> <jta-data-source>java:/ejavaDS</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="create"/> <property name="hibernate.show_sql" value="true"/ </properties> </persistence-unit> </persistence>
referenced by name
• global JNDI name by which provider references resource (will be used when deployed within server) • may use properties element in Java SE environments that lack JNDI
• vendor-specific way to configure persistence provider
v110912 Java Persistence: EntityManager 199
ANOTHER EXAMPLE PERSISTENCE.XML <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="jpaDemo"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.Provider"/> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost:9001"/> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> <property name="hibernate.connection.password" value=""/> <property name="hibernate.connection.username" value="sa"/> <property name="hibernate.show_sql" value="false"/> <property name="hibernate.hbm2ddl.auto" value="create"/> </properties> </persistence-unit> </persistence
200
PERSISTENCE.XML ELEMENTS name – identity to reference Persistence Unit provider – fully qualified name of javax.persistence.PersistenceProvider
not needed if provider found in classpath acceptable mapping-file – resource path to optional mapping file
can be used to specify <class>es or specify/override @Annotation details
jta-data-source vendor-specific reference to data source using JTA transactions
non-jta-data-source vendor-specific reference to data source using RESOURCE_LOCAL
transactions jar-file
optional/additional jar file to scan for classes class
specifies entity classes not automatically scanned by provider exclude-unlisted-classes
if set, provider will not automatically scan archive for entity classes properties
may be used to provide vendor-specific properties to configure persistence providers
201
JAVA SE STEPS Startup
Get EntityManagerFactory Runtime
Create EntityManager Start Transaction Interact with Entity Manager Commit Transaction Close EntityManager
Shutdown Close EntityManagerFactory
202
UPDATING ENTITIES Updates to managed entities automatically get
propagated to database according to flush policy public Author update(Author author) { Author dbAuthor = em.find(Author.class,author.getId());
dbAuthor.setFirstName(author.getFirstName()); dbAuthor.setLastName(author.getLastName()); dbAuthor.setSubject(author.getSubject()); dbAuthor.setPublishDate(author.getPublishDate()); return dbAuthor; } Note that if author passed in was already managed...
the changes have already been queued the dbAuthor returned from the find() will be the same object as author the sets are unnecessarily changing the values of the Author to their
current values
v110912 Java Persistence: EntityManager 203
(OPTIONAL!)POTENTIAL UTILTITY CLASS package ejava.examples.dao.jpa; import java.util.HashMap; import java.util.Map; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class JPAUtil { private static final Map<String, EntityManagerFactory> factories = new HashMap<String, EntityManagerFactory>(); public static EntityManagerFactory getEntityManagerFactory(String puName) { EntityManagerFactory emf = factories.get(puName); if (emf == null) { synchronized(factories) { emf = factories.get(puName); if (emf == null) { emf = Persistence.createEntityManagerFactory(puName); factories.put(puName, emf); } } } return emf; } public static void close() { synchronized(factories) { for(String puName : factories.keySet()) { factories.get(puName).close(); } factories.clear(); } } }
Q&A
Topic : JavaMail API (1) Sending and Receiving Emails Kaster Nurmukan
AGENDA Overview of JavaMail API SMTP POP MIME javaMail API HTML Email Email With attachment
MAIL API Java Mail API is an easy and standard way of
sending and receiving emails Java Mail API supports following Protocols:
SMTP POP IMAP MIME
SMTP Simple Mail Transfer Protocol
Usually used for sending emails from clients Also used for relaying emails from one server to another
SMTP
POP Post office protocol Currently Version 3 in use (Pop3 RFC1939) Used at client side to check the emails that are received in
the mailbox for a user
IMAP Stands for Internet Message Access Protocol Currently IMAP4 (RFC2060) in use More advanced protocol for email access that
allows multiple folder management on server, periodic backups and several other advanced features.
MIME Multi-purpose Internet Mail Extention Defines the contents that are to be transferred in an email
WHAT DO YOU NEED TO USE JAVA MAIL? You should have following two APIs
Java Mail API JavaBeans Activation Framework(JAF) JAF is included in JDK6
MAIL API As the name says, is used for sending and receiving
emails. Mail API requires JavaBeans Activation Framework
JAF JavaBeans Activation Framework
Helps programmers to Determine the type of an arbitrary piece of data
Encapsulates access to it Discovers operations that can be performed on it Get from
WHERE TO GET? Both APIs can be downloaded from http://www.oracle.com/technetwork/java/javaee/downloads
/ JAF Get from • http://www.oracle.com/technetwork/java/jaf11-
139815.html#download
• But you still need Email Server first : You can use existing server out site internet ,example: Gmail You can download local Mail server in your PC
http://james.apache.org/download.cgi#Apache_James_Server
HOW TO INSTALL? Un-zip the javamail.zip and jaf.zip into some folder Put mail.jar from javamail folder to the classpath Put activation.jar from jaf folder to classpath
JAVA MAIL CLASSES
You must know following classes before you start Session Message Address Transport Store Folder
JAVAX.MAIL.SESSION Defines a basic mail session Everything in mail api works due to this session
JAVAX.MAIL.MESSAGE
Represents an email message that is either created to be sent to the recipient or is received from someone.
Message is an Abstract class MimeMessage is the sub-class of message
that understands most MIME types and is most commonly used for email handling
JAVAX.MAIL.ADDRESS Represents an email addres Address is an abstract class javax.mail.Internet.InternetAddress is the sub-class of
Address
MESSAGE REPRESENTATION
MimeMessage
Headers
Session
Address[] To Address[] From
String subject Date sentDate
Message Content: String text
Properties
TRANSPORT This class speaks the protocol specific language to send
messages. (Usually SMTP)
STORE AND FOLDER When receiving email
We create a session Connect to a store with our username and password Get specific folders (usually inbox) And start receiving Message objects
SENDING AN EMAIL
//Create properties object Properties p = System.getProperties(); p.put("mail.smtp.host", "202.125.140.71"); // Get session Session s = Session.getDefaultInstance(p,null);
SENDING AN EMAIL (CONT)
Message m = new MimeMessage(s); InternetAddress to = new InternetAddress("[email protected]"); InternetAddress from = new InternetAddress("[email protected]",
"Bill Gates"); m.setContent("yeah this is the body", "text/plain"); m.setFrom(from); m.setRecipient(Message.RecipientType.TO, to); m.setSubject("de subject"); Transport.send(m);
CHECKING MAILS Properties props = new Properties(); Session session = Session.getDefaultInstance(props,
null); Store store = session.getStore("pop3"); store.connect(host, username, password); Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY);
CHECKING MAILS(CONT) Message message[] = folder.getMessages(); for (int i=0, n=message.length; i<n; i++) { System.out.println(i + ": " +
message[i].getFrom()[0] + "\t\t" + message[i].getSubject());
} folder.close(false); store.close();
OUTPUT 0: Hans<[email protected]> test 1 1: [email protected] de subject 2: [email protected]@microsoft.com de subject 3: [email protected] de subject 4: [email protected] de subject 5: Bill Gates <[email protected]> de subject
LET’S TRY IT OUT!!! Send email using Gmail SMTP server Set Mail content type (text/plain)
HTML EMAIL
• You can also send HTML email with JavaMail. HTML email can be used to – Use different size fonts – imbed images into your email – Use different colored text, bold, italic, etc.
HTML EMAIL
• With HTML email, – you set the mime message content type to
"text/html" – call the setContent() method to set your
html content • It helps to know a little HTML!
MAIL SECURITY
Virtually all mail servers require a username and password to receive email Some mail servers require a username and password to send an email (by
default, James does not). This prevents spammers from hijacking the mail server to send
unauthorized email JavaMail supports this username/password authorization and authentication
To implement this, you get a transport object from the mail session and call the connect() method with the mail host, username, and password
See next slide for code example
HTML EMAIL EXAMPLE Example of sending html message with an imbedded image using username/password
authorization MimeMessage msg = new MimeMessage(mailSession); msg.setFrom(new InternetAddress("[email protected]")); msg.addRecipient(Message.RecipientType.TO, new InternetAddress(“[email protected]")); msg.setSubject(subject); String html = "<html><body><b>MY SPAM</b><br><img src='http://www.wrfportal.org/images/NOAA_logo.jpg'> </body></html>"; msg.setContent(html, "text/html"); Transport transport = mailSession.getTransport("smtp"); transport.connect("localhost","user", "passwd"); msg.saveChanges(); transport.sendMessage(msg, msg.getAllRecipients()); transport.close();
MULTIPART REPRESENTATION
MimeMessage Headers Session
Message Content: Multipart MimeBodyPart MimeBodyPart
String text
DataHandler
FileDataSource File
String fileName
JAVAX.ACTIVATION.DATASOURCE Interface that allows access to file type and to
streams that can manipulate the file public String getContentType() returns the name of
the MIME file type Implemented by javax.Activation.FileDataSource Used by JavaMail to create and retrieve e-mail
attachments Constructors
FileDataSource(File file) FileDataSource(String filename)
JAVAX.ACTIVATION.DATAHANDLER Wrapper for DataSource objects so that the user
does not need to manipulate the bytes for each file Constructors
DataHandler(DataSource ds) DataHandler(Object obj, String mimeType)
Public Object getContent() Returns the data as the object that represents its content type (ie runing this method on a text message returns a String)
JAVAX.MAIL.PART REVISITED Allows manipulation of DataHandlers
public void setDataHandler(DataHandler dh) public DataHandler getDataHandler()
Other methods abstract user away from need to directly manipulate DataHandler public void setContent(Object object, String
contentType) public Object getContent()
JAVAX.MAIL.MIMEBODYPART Implements the Part interface (indirectly through a few
abstract classes) Contains the content for a single part of an e-mail
message Uses several methods to manipulate content directly
or through DataHandler or streams Key Methods
public void setText(String text): for text/plain content, makes a String into the message content
public void setDataHandler(DataHandler dh) sets the content using a DataHandler (which may be text or any other permitted content)
public void setFileName(String filename) sets the filename associated with the content, if the content represents a file
JAVAX.MAIL.MULTIPART Container that holds multiple parts Each part is indexed, starting with 0 A Multipart object may be a part within another
Multipart object Key Methods
public void addBodyPart(BodyPart part) public void addBodyPart(BodyPart part, int index) public int getCount() returns the number of BodyPart objects
EMAIL ATTACHMENTS -1 To append an email attachment, you need to send a "multipart" message
Create your MimeMessage object as usual, setting the from address, to address, subject, etc...
Create a MimeBodyPart object for your main message and set its text (or content) to be your message
Create a MimeBodyPart object for your attachment and call its setContent() method to attach your file
Create a Multipart object and add both body parts to it. Call your MimeMessage's setContent() method, passing in your Multipart
object Call Transport.send() to send the message
Whew!!!
EMAIL ATTACHMENT EXAMPLE-1 MimeMessage msg = new MimeMessage(getMailSession()); msg.setFrom(new InternetAddress("[email protected]")); msg.addRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]")); msg.setSubject("RE: Oracle vs SQL Server"); //Create the main message (body) part for text MimeBodyPart mainBodyPart = new MimeBodyPart(); mainBodyPart.setText("Here is my message");
EMAIL ATTACHMENT EXAMPLE-2 //Create attachment body part MimeBodyPart attachBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource("1.jpg"); attachBodyPart.setDataHandler(new DataHandler(source)); attachBodyPart.setFileName("1.jpg"); //Now create the multipart and add the parts Multipart multipart = new MimeMultipart(); multipart.addBodyPart(mainBodyPart); multipart.addBodyPart(attachBodyPart); //add the multipart to the original Mime message msg.setContent(multipart); Transport.send(msg);
REFERENCE http://www.oracle.com
Q&A
Topic : JavaMail API Kaster Nurmukan
AGENDA Overview of JavaMail API Javax.mail.Session Javax.mail.Authenticator and
PasswordAuthentication Javax.mail.Message Javax.mail.Part Javax.mail.Multipart and BodyPart Javax.mail.internet.MimePart • javax.mail.Service • javax.mail.Transport
JAVAMAIL API We are going to cover the following topics in JavaMail API:
• java.mail.Session • javax.mail.Authenticator and PasswordAuthentication • javax.mail.Message • javax.mail.Part • javax.mail.Multipart and BodyPart • javax.mail.internet.MimePart and MimeMessage • javax.mail.internet.MimeMultipart and MimeBodyPart • javax.mail.Service • javax.mail.Transport
249
JAVAX.MAIL.SESSION Acts as a factory for the installed Transport and
Store implementations. Responsible for managing a user’s mail
configuration settings and handling authentication for the individual services used during the session.
A way to associate providers with a particular set of user properties and an authentication mechanism.
250
JAVAX.MAIL.SESSION Can be stored as an object in the servlet’s session so
that the appropriate relationship can be maintained. The application will be retrieving the correct Transport
and Store objects based on the current user’s settings by interacting with the session.
Server-side applications will likely be creating a session for each connected client.
251
JAVAX.MAIL.SESSION CONSTRUCTING A SESSION JavaMail session class does not implement public
constructors. Potential clients are expected to use the one of the
following public static methods to acquire session reference:
• Static Session getInstance (Properties prope, Authenticator authenticator)
//constructs and returns a new unshared Session instance with the specified Properties and Authenticator.
• Static Session getDefaultInstance (Properties prope, Authenticator authenticator)
//returns the default (shared) Session instance.
252
JAVAX.MAIL.SESSION CONSTRUCTING A SESSION GetInstance () method returns a new instance with each
invocation. getDefaultInstance () repeatedly returns the same instance, as
long as the specified Authenticator is a reference to the same instance passed in when the default session was initially created. useful when developing single-user applications.
253
JAVAX.MAIL.SESSION CONSTRUCTING A SESSION Java.util.Properties object that is passed into both of
these two methods is usually obtained by invoking the system.getProperties method. JavaMail-specific properties can then be added:
Properties props = system.getProperties (); props.put (“mail.transport.protocol”, “smtp”); props.put (“mail.smtp.host”, “mail.foo.com”); Session session = Session.getInstance (props, null);
254
JAVAX.MAIL.SESSION SESSION PROPERTIES Mail.transport.protocol the default transport protocol,
implemented by Transport class returned from Session.getTransport ().
Mail.store.protocol the default store protocol, implemented by Store class returned from Session.getStore ().
Mail.host the default host for both Store and Transport protocol.
Mail.user the default user name for both Store and Transport protocol.
Mail.from the user’s return e-mail address Mail.protocol.host the host specific to a particular protocol. Mail.protocol.user the default user name specific to a
particular protocol. Mail. Debug the default debug setting for sessions. This can
be overridden with setDebug (boolean).
255
JAVAX.MAIL.SESSION SESSION PROPERTIES * Properties getProperties (); //return the properties collection specified when
constructing the session. * String getProperties (string name); //return the value of the specified property or null if it
does not exist. * void setDebug (boolean debug); //set the debug setting for this session. If it set true,
debug massage will be output to the console by both the session and its providers.
* boolean getDebug (); //return the debug setting for this session. Can be used to
determine whether debug message should be output.
256
PASSWORDAUTHENTICATION
* Javax.mail.passwordAuthentication getPasswordAuthentication ();
//Invoked by a Session when password authentication is needed. Any number of implementations is possible as long as a PasswordAuthentication instance is returned.
* PasswordAuthentication (String username, String password);
//Returning a PasswordAuthentication instance is simple a matter of invoking this constructor. This should be constructed and returned in the client’s implementation of getPasswordAuthentication. 257
JAVAX.MAIL.AUTHENTICATOR AND PASSWORDAUTHENTICATION The Authenicator class also includes several protected
methods that provide access to the typical properties that would enable building a reasonable explicit prompt for the user:
protected String getRequestingProtocol (); protected int getRequestingPort (); protected InetAddress getRequestingSite (); protected String getRequestingPrompt (); protected String getDefaultUserName ();
258
JAVAX.MAIL.AUTHENTICATOR AND PASSWORDAUTHENTICATION Fully functional Authenticator: Import javax.mail. *; Import javax.swing. *; Public class MyAuthenticator extends Authenticator { public PasswordAuthentication getPasswordAuthentication (); { string password = JOptionPane.showInputDialog ( “Connecting to” + getRequestingProtocol() + “mail service on host” + getRequestingSite() + “, port” + getRequestingPort() + “as user” + getDefaultUserName () + “.\n” + getRequestingPrompt (); if (password == null) return null; else return new PasswordAuthentication (getDefaultUsername(),
password); } }
259
JAVAX.MAIL.MESSAGE
260
<interface> Java.mail.part
Javax.mail.Message
Javax.mail.internet.MimeMessage
<interface> Javax.mail.internet.Mimepart
Javax.mail.multipart
Javax.mail.Bodypart
Javax.mail.internet.MimeMultipart
Java.mail.internet.MimeBodypart
JAVAX.MAIL.MESSAGE CONSTRUCTING A MESSAGE Two most common ways for a Message
implementation to be constructed:
• MimeMessage (Session session); //Constructs a new and empty (of headers, content, and
flags) MimeMessage in the specified session. • Message reply (boolean replyToAll); //Returns a new Message with headers suitable to be
used as a reply to this message. The subject is automatically prefixed with the string “Re:”. 261
JAVAX.MAIL.MESSAGE MASSAGE HEADER The source for an internet message: Message-ID: <…> Date: Mon, 29 May 2000 11:40:41 … From: [email protected] To: [email protected] Subject: … Mime-Version: 1.0 Content-Type: text/plain; charset=ascii Content-Transfer-Encoding: 7bit I have several contact with the outside world… 262
JAVAX.MAIL.MESSAGE MESSAGE HEADERS Original standard for messages is problemetic in sending
arbitrarily sized binary attachments. MIME (Multipurpose Internet Mail Extensions) extends the
capabilities of Internet messages while maintaining compatibility with the previous standard.
JavaMail API exposes the headers as standard getters and setters.
In the most prevelent message formats, the documentation for the Message methods will often refer to the headers that are set or retrieved by its most common subclass, MimeMessage. The Message class, however, was designed as an abstract interface to any possible implementation. 263
JAVAX.MAIL.MESSAGE MESSAGE HEADERS The From: Header • Void setFrom (); //The no parameter form sets the From header to the address
specified in the Session’s mail.user property or if not present, user.name.
• Void setFrom (Address address); //Set the from header to the spedified address by passing an
Address object. • Void addFrom (Address [] addresses); //If multiple address • Address[] getFrom (); //Implemented by a getter, returns an array of the Addresses in
the From header. 264
JAVAX.MAIL.MESSAGE MESSAGE HEADERS The Reply-To: Header • Void setReplyTo (Address[] addresses); //Sets the Reply-To header to the specified addresses.
These addresses are automatically set as recipients when constructing a message using the reply () method.
• Address[] getReplyTo (); //Gets an array of addresses that replies should be sent
to or null if this can not be determined. • The MimeMessage implementation checks for the
existence of a Reply-To header first. 265
JAVAX.MAIL.MESSAGE MESSAGE HEADERS
The To:, Cc; and Bcc: Headers To: normal recipients cc: carbon copied recipients Bcc: blind carbon copied recipients Void setRecipient (Message.RecipientType type, Address address) Void setRecipients (Message.RecipientType type, Address[]
addresses) // Set the To, Cc, or Bcc header to the specified address(es). Void addRecipient (Message.RecipientType type, Address address) //Add the specified address to any of the existing To, Cc, or Bcc
headers. Address[] getRecipients (Message.RecipientType type) or Address[]
getRecipients () // Return the addresses of the recipients.
266
JAVAX.MAIL.MESSAGE MESSAGE HEADERS The Subject: Header In Message class: void setSubject (string subject) string getSubject () The Date: Header void setSentDate (Date date) Date getSentDate () Date getReceivedDate ()
267
JAVAX.MAIL.MESSAGE MESSAGE HEADERS Folder and Message Number • Messages that are persisted in some Store are organized into
folders. Each message within a folder is temporarily assigned a unique (within the Folder) number to help identify it to the Store provider.
• Folder getFolder (); //Gets the Folder that contains this Message or null if this is
either a new or nested Message. • Int getMessageNumber (); //Returns the message number corresponding to this message.
268
JAVAX.MAIL.MESSAGE MESSAGE FLAGS Why Flags? Not all providers support flagging messages but there is a
mechanism by which a client can determine what flags can be set. Some advanced implementations make it possible to set user-defined flags (usually represented as arbitrary strings of the user or user agent’s choosing )on a message.
269
JAVAX.MAIL.MESSAGE MESSAGE FLAGS Inorder to support both the typical flagging of messages using
the typical static final constants and the user defined flagging using strings, the JavaMail provides a fairly clever approch that centers on the Flags class:
270
Outer class:Flags acts like a container for these Flag instance as well as for arbitrary String instances.
Inner class:Flag Defines several static instances of itself to represent the standard set of flags.
JAVAX.MAIL.MESSAGE MESSAGE FLAGS In Flag class: Void add (flags.flag flag); //Add the specified system flag. Void add (string flag); //Add the specified user flag. Boolean contains (flags.flag flag); //Test for system flag (flag). Boolean contains (string flag); //Test for user flag (flag). Void remove (flags.flag flag); //… Void remove (string flag); Flag.flag[] getSystemFlags (); String[] getUserFlags (); In Message class: Void setFlag (flags.flag flag, boolean set); //Set or clear individual flag Void setFlags (Flags flag, boolean set); //Set or clear all of the
individual flags in specified flag object (inner class). Some system flags: ANSWERED DELETED DRAFT FLAGGED
RECENT SEEN USER
271
JAVAX.MAIL.PART This defines the methods used for storing and retrieving the
content of a message or part of one, as in Multipart and MimeMultipart classes.
It also defines the standard properties that both whole messages and body parts have in common.
272
JAVAX.MAIL.PART ACTIVATION JavaBeans Activation Framework (JAF) is a little known API.
The JavaMail API is one of the few products that make use of the JAF.
What is the main purpose of JAF? After the advent of the MIME extensions, JavaMail leverages
the functionality provided by the JAF in order to provide a simple and consistent interface to any number of disparate data sources. Javax.activation.DataHandler class provides this interface. It is simply a convenient wrapper around some implementation of the javax.activation.DataSource interface. Two useful such implementations, javax.activation.FileDataSource and URLDataSource, are provided by part of the JAF.
273
JAVAX.MAIL.PART ACTIVATION DataSource and its encapsulating DataHandler can
provide access to the raw bytes of a data type with their getInputStream (), and getOutputStream () methods.
The DataSource is responsible for providing the streams.
The Message implementation uses these streams to transmit and retrieve a part’s content, regardless of what type it really is.
274
JAVAX.MAIL.PART ACTIVATION A higher and more useful level of abstraction:
getContent () in DataHandler. 1. Return an actual Java instance that can be immediately
downcast to the appropriate Java class. 2. Can be used directly by programmers by invoking
whatever methods available in that class. 3. If the MIME type for the content has a registered
javax.activation.DataContentHandler implementation, an object specific to that type will be returned. Otherwise, in InputStream is returned.
275
JAVAX.MAIL.PART CONTENT Void setDataHandler (javax.activation.DataHandler dh) //Set the part’s
content to the specified DataHandler. Javax.activation.DataHandler getDataHandler (); //Return the DataHandler for the content. Void setContent (java.lang.object object, string type); //Set the content for this part based on the specified type. Void setText (string text); //Set the content for this part to the specified string with a content type
of ‘text/plain’. Void setContent (multipart mp); //Set the content for this part to the specified Multipart object. The
content will be set to multipart/mixed. Java.lang.Object getContent (); //Return the content for this part, which can be downcast to an
appropriate object based on the content type or InputStream if the content type does not have a registered DataContentHandler.
276
JAVAX.MAIL.PART CONTENT
One simple example: How to set a part’s content to some plain text: part.setDataHandler (new DataHandler (text, “text/plain”)); or part.setContent (text, “text/plain”); or part.setText (text); Retrieving a part’s content always uses the getContent ()
method. How to retrieve the plain text as a string object: String text = (String) part.getContent ();
277
JAVAX.MAIL.PART CONTENT If the part’s type were not registered content type, the resulting
object would have been an InputStream that can be used to retrieve the raw bytes of the content.
Example: save unregistered content to disk so that the user can use a separate application to process the data:
object content = part.getContent (); if (content instanceof InputStream) { InputStream is = (InputStream) content; OutputStream os = new FileOutputStream (“content”); int n; byte buffer[] = new byte [1024]; while ( ( n = is.read (buffer) ) > 0) { os.write(buffer, 0, n); } is.close (); }
278
JAVAX.MAIL.PART PART HEADERS The Part interface exposes the necessary functionality for setting
and retrieving any imaginable header’s value. Like the Message class, if the part is in a modifiable state, the
following methods can modify the part’s headers: void addHeader (String headerName, string headerValue); void setHeader (String headerName, string headerValue); void removeHeader (string headerName); String[] getHeader (string headerName); java.util.Enumeration getAllHeaders (); java.util.Enumeration getMatchingHeaders (sting [] headernames); java.util.Enumeration getNonMatchingHeaders (sting []
headernames); 279
JAVAX.MAIL.PART PART HEADERS A part’s description, disposition, and file name can be
specified using the following methods: void setDescription (string description); void setDisposition (string disposition); //User should use
either one of the Part interface constrains, ATTACHMENT or INLINE.
string getDisposition (); string setFilename (string filename); string getFilename (); Several other methods: int getLineCount (); int getSize (); //Return the size of the part’s content in bytes. void writeTo (OutputStream os); //Write this part to the
specified output stream.
280
JAVAX.MAIL.MULTIPART AND BODYPART
Multipart messages are composed of one or more body parts.
The abstract Multipart class defines the methods necessary for collecting these body parts.
Each component in a multipart message needs its own set of headers and content. Then BodyPart class needs the functionality exposed by the Part interface.
To, From, Date, Subject, etc, are specified at the message level, not on a part-by-part level.
281
JAVAX.MAIL.MULTIPART AND BODYPART
Some relative methods: Void addBodyPart (BodyPart part); Void addBodyPart (BodyPart part, int index); Boolean removeBodyPart (BodyPart part); Void removeBodyPart (int index); Int getCount (); //Return the number of body parts
comprising this multipart. BodyPart getBodyPart (int index); String getContentType (); Void setParent (Part parent); //set the parent part Part getParent ();
282
JAVAX.MAIL.INTERNET.MIMEPART The MimePart interface extends Part with several MIME-specific
methods including some that provide lower-level access to the message headers:
Void setText (string text, string charset) //Set the content for this part to the specified text and encode it using specified charset.
String getEncoding () //Return the value of the Content-Transfer-Encoding header. This header is appropriately set when saveChanged () is invoked on a message containing this part.
String getContentID () //Return the value of the Content-ID. Void setContentLanguage (string[] languages) Void setContentMD5 (string md5) //Set Content-MD5 header, to ensure
that a part’s content has not been altered during transit. 283
JAVAX.MAIL.INTERNET.MIMEPART Some other methods:
String getHeader (string headerName, string delimiter)
//Return all the values for a given header in a single string separated by the specified delimiter.
Enumeration getAllHeaderLines () //Return an enumeration of the raw header lines in the part.
Enumeration getMatchingHeaderLines (string[] names) Enumeration getNonMatchingHeaderLines (string[]
names)
284
JAVAX.MAIL.INTERNET.MIMEMESSAGE MimeMessage class is the only Sun-provided concrete
implementation of Message. MimeMessage implements all of the abstract methods
defined in Message as well as those defined in both Part and MimePart.
285
JAVAX.MAIL.INTERNET.MIMEMESSAGE An example: complete application that opens a session, constructs a message, and outputs it
to the screen: import java.io.*; import javax.activation.*; import javax.mail.*; import javax.mail.internet.*; public class MimeMessageExample { // starts here // create a new session instance; MimeMessage message = new MimeMessage (session); message.setFrom (new InternetAddress ([email protected])); message.setRecipient (Message.RecipientType.To, new InternetAddress
([email protected])); message.setSubject (“No mail at all”); string text = “I have several contact with the outside world\r\n”+”I have food so don’t
worry\r\n”; message.setText (text); message.saveChanges (); message.writeTo(System.out); }
286
JAVAX.MAIL.INTERNET.MIMEMULTIPART AND MIMEBODYPART Like MimeMessage, MimeMultipart and MimeBodyPart are the
concrete implementations that most clients will be using when constructing multipart messages.
MimeMultipart introduces some methods as: void setSubType (string subtype); //Sets the subtype of this multipart to
the specified string. This defaults to ‘mixed’. BodyPart getBodypart (string contentID); //Returns the body part with
the specified content ID or null if not found.
287
JAVAX.MAIL.INTERNET.MIMEMULTIPART AND MIMEBODYPART An example: how a MimeMuiltipart is constructed and given two MimeBodyParts (analogous to ‘attaching’ a file to a message):
import java.io.* … // Import the same classes as previous one. public class MimeMultipartExample { //Start here //Create a new session instance. Message message = new MimeMessage (session); message.setFrom(new InternetAddress (“…@…”)); message.setRecipient (message.RecipientType.To, new InternetAddress
(“…@…”)); message.setSubject (fileName); //Text part BodyPart bodyPart1 = new MimeBodyPart (); bodyPart1.setText (“…”); //File part BodyPart bodyPart2 = new MimeBodyPart (); FileDataSource fileDataSource = new FileDataSource (fileName); //set DataHandler and Filename for bodyPart2
288
JAVAX.MAIL.INTERNET.MIMEMULTIPART AND MIMEBODYPART Example continued:
multipart multipart = new MimeMultipart (); multipart.addBodyPart (bodyPart1); multipart.addBodyPart (bodyPart2); message.setContent (multipart); message.saveChanges (); message.writeTo (system.out); } //End of the program.
289
JAVA.MAIL.SERVICE JavaMail API provides an abstraction for two types of services that
sessions can create, Transports and Stores. The behavior common to both was extracted out into an even higher abstraction, the Service.
Behavior common to Transport and Store: Require that a connection be established before messages can be
sent or retrieved . Support some optional authentication mechanism. Services can optionally be identified by a URLName, e.g, a URLName
designating a user’s POP3 account may look like: pop3://username:password@hostname:port. The URLName class represents a string that includes whatever
information necessary in order to make a connection to some server.
290
JAVA.MAIL.SERVICE Relative methods:
URLName getURLName() Void connect () //Connect to the service using any suitably
available default values for the host, port, and user. Void connect (string host, string user, string password)
//Using specified user and password for authentication. Boolean isConnected () Void close ()
291
JAVAX.MAIL.TRANSPORT Sending a message is achieved using a Transport. Sun’s
JavaMail implementation comes with a fully functional SMTP transport that could be the only transport provider we need.
Transport class contains two static methods that make sending a message simple:
Static Transport.send (Message message) //Send the message using an appropriate transport for each of the message’s recipients’ address type.
Static Transport.send (Message message, Address[] recipients) // Ignore the message’s recipients and instead sending it to the specified recipients. 292
JAVAX.MAIL.TRANSPORT An example capable of sending a message to any user on the internet: import java.util.*; import java.mail.*; import javax.mail.internet.*; public class TransportSendExample { //Start here // Initialize smtpHost, fromAddress, toAddress. Properties properties = system.getProperties (); properties.put (“mail.smtp.host”, smtpHost); Session session = Session.getInstance (properties, null); MimeMessage message = new MimeMessage (session); //Set From and Recipients for message as we did in the previous example message.setSubject (“Javemail example”); message.setText (“…”); Transport.send (message); }
293
JAVAX.MAIL.TRANSPORT Five different means by which the correct transport can be constructed and
returned to the user: Transport getTransport () // Return a transport that implements the protocol
specified in the session’s mail.transport protocol property. Transport getTransport (string protocol) // Return a transport implemented by
the specified protocol. Transport getTransport (Address address) // Return a transport capable of
sending a message to the specified address type. Transport getTransport (URLName url) //Return a transport that implements
the protocol as found in the ‘scheme’ part of the specified URL name. Transport getTransport (Provider provider) //Return a transport implemented
by the specified provider.
294
REFERENCE http://www.oracle.com
Q&A
Topic : JPQL Java Persistence Query Language Kaster Nurmukan
INTRODUCTION • The Java Persistence API specifies a query
language that allows to define queries over entities and their persistent state
• JPQL is an extension of EJB QL • More robust flexible and object-oriented
than SQL • The persistence engine parse the query
string, transform the JPQL to the native SQL before executing it
CREATING QUERIES • Query instances are obtained using:
• EntityManager.createQuery (dynamic query) • EntityManager.createNamedQuery (static query)
• Query API: getResultList() – execute query returning multiple results getSingleResult() – execute query returning single result executeUpdate() – execute bulk update or delete setFirstResult() – set the first result to retrieve setMaxResults() – set the maximum number of results to retrieve setParameter() – bind a value to a named or positional parameter setHint() – apply a vendor-specific hint to the query setFlushMode()– apply a flush mode to the query when it gets run
STATIC (NAMED) QUERIES • Defined statically with the help of @NamedQuery
annotation together with the entity class • @NamedQuery elements:
• name - the name of the query that will be used with the createNamedQuery method
• query – query string
@NamedQuery(name="findAllCustomers",
query="SELECT c FROM Customer")
Query findAllQuery = entityManager.createNamedQuery(“findAllCustomers”); List customers = findAllQuery.getResultList();
MULTIPLE NAMED QUERIES • Multiple named queries can be logically defined with
the help of @NamedQueries annotation
@NamedQueries( {
@NamedQuery(name = “Mobile.selectAllQuery”
query = “SELECT M FROM MOBILEENTITY”),
@NamedQuery(name = “Mobile.deleteAllQuery”
query = “DELETE M FROM MOBILEENTITY”)
} )
NAMED PARAMETERS • Named parameters are parameters in a query
that are prefixed with a colon (:) • To bound parameter to an argument use
method: • Query.setParameter(String name, Object value)
public List findWithName(String name) {
return em.createQuery(
"SELECT c FROM Customer c WHERE c.name LIKE :custName")
.setParameter("custName", name)
.getResultList();
}
POSITIONAL PARAMETERS • Positional parameters are prefixed with a
question mark (?) followed the numeric position of the parameter in the query
• To set parameter values use method: • Query.setParameter(integer position, Object value)
public List findWithName(String name) {
return em.createQuery(
“SELECT c FROM Customer c WHERE c.name LIKE ?1”)
.setParameter(1, name)
.getResultList();
}
DYNAMIC QUERIES • Dynamic queries are queries that are defined
directly within an application’s business logic
• Worse efficiency and slower query execution, as the persistence engine has to do all the parsing and validation stuffs, along with mapping the JPQL to the SQL at the run-time
public List findAll(String entityName){
return entityManager.createQuery(
"select e from " + entityName + " e")
.getResultList();
}
NATIVE QUERIES • Queries may be expressed in native SQL • Support for cases where it is necessary to
use the native SQL of the target database in use
Query q = em.createNativeQuery(
"SELECT o.id, o.quantity, o.item " +
"FROM Order o, Item i " +
"WHERE (o.item = i.id) AND (i.name = 'widget')",
com.acme.Order.class);
•@SqlResultSetMapping annotaton is used for more advanced cases
QUERY OPERATIONS – MULTIPLE RESULTS
• Query.getResultList() will execute a query and may return a List object containing multiple entity instances
• Will return a non-parameterized List object • Can only execute on select statements as
opposed to UPDATE or DELETE statements • For a statement other than SELECT run-time IllegalStateException will be thrown
Query query = entityManager.createQuery(“SELECT C FROM CUSTOMER”);
List<MobileEntity> mobiles = (List<MobileEntity>)query.getResultList();
QUERY OPERATIONS – SINGLE RESULT • A query that returns a single entity object
• If the match wasn’t successful, then EntityNotFoundException is returned
• If more than one matches occur during query execution a run-time exception NonUniqueResultException will be thrown
Query singleSelectQuery = entityManager.createQuery(
“SELECT C FROM CUSTOMER WHERE C.ID = ‘ABC-123’”);
Customer custObj = singleSelectQuery.getSingleResult();
PAGING QUERY RESULTS int maxRecords = 10; int startPosition = 0;
String queryString = “SELECT M FROM MOBILEENTITY”;
while(true){
Query selectQuery = entityManager.createQuery(queryString);
selectQuery.setMaxResults(maxRecords);
selectQuery.setFirstResult(startPosition);
List<MobileEntity> mobiles = entityManager.getResultList(queryString);
if (mobiles.isEmpty()){ break; }
process(mobiles); // process the mobile entities
entityManager.clear(); // detach the mobile objects
startPosition = startPosition + mobiles.size();
}
FLUSHING QUERY OBJECTS
• Two modes of flushing query objects • AUTO (default) and COMMIT
• AUTO - any changes made to entity objects will be reflected the very next time when a SELECT query is made
• COMMIT - the persistence engine may only update all the state of the entities during the database COMMIT
JPQL STATEMENT LANGUAGE • JPQL statement types:
• SELECT, UPDATE, DELETE • Supported clauses:
• FROM • WHERE • GROUP_BY • HAVING • ORDER BY • …
• Conditional expressions, aggregate functions,…
JPQL ENHANCEMENTS • Simplified query syntax • JOIN operations • Group By and Having Clause • Subqueries • Dynamic queries • Named parameters • Bulk update and delete
OO-STYLE VS. SQL-STYLE QUERIES • The main difference is that you query the
application model, i.e. the entities, rather than any database tables
• Productivity can be increased if OO-style quries, e.g.
employeeXYZ.getManager().getAddress()
are automatically translated by the ORM engine into correct SQL code, e.g.
SELECT t3.* FROM EMP t1, EMP t2, ADDR t3
WHERE t1.EMP_ID = “XYZ” AND t1.MGR_ID = t2.EMP_ID AND t2.ADDR_ID = t3.ADDR_ID
• Notice that the two-step object traversal was packed into a single DB query
RESOUCE
• JPQL Language Reference http://edocs.bea.com/kodo/docs41/full/html/ejb3_langref.html
• JPA Query API http://www.javabeat.net/javabeat/ejb3/articles/2007/04/introduction_to_java_persistence_api_jpa_ejb_3_0_6
• Standardizing Java Persistence with the EJB3 Java Persistence API – Query API http://www.onjava.com/pub/a/onjava/2006/05/17/standardizing-with-ejb3-java-persistence-api.html?page=last&x-showcontent=text
Q&A
Topic : JPA Criteria API Kaster Nurmukan
AGENDA Powerful Query Capabilities HQL Prototypical Use of Query API Criteria Queries Prototypical Use of Criteria API How to use the JPA Criteria API Examples from simple to complex
POWERFUL QUERY CAPABILITIES ● HQL: The Hibernate Query Language ● object-oriented ● Criteria API ● powerful object model for constructing and executing queries ● Query by Example ● Not locked in: can perform SQL queries, including stored procedure invocations
317
HQL ● Powerful object-based query language ● Hibernate translates HQL to SQL ● HQL statements are shorter, more readable than their SQL counterparts
318
PROTOTYPICAL USE OF QUERY API String hql = "from Customer c where c.age > :age"; Query q = session.createQuery(); q.setInteger("age", 33); q.setFirstResult(20); q.setMaxResults(10); // fetch the third page List customers = q.list(hql);
CRITERIA QUERIES ● What makes the Criteria API powerful is that it allows queries to be specified by composition. ● This means that queries can be constructed dynamically.
PROTOTYPICAL USE OF CRITERIA API Criteria c = session.createCriteria(Customer.class); c.add( Restrictions.ilike("name", "Albert%") ); c.addOrder( Order.asc("age") ); c.setMaxResults(20); c.list(); // entire sequence of calls can also be chained, // like so: session.createCriteria(Customer.class). add( Restrictions.ilike("name", "Albert%") ). addOrder( Order.asc("age") ). setMaxResults(20). list();
THE NEW PROBLEM JPQL CAN’T,BUT JPA CRITERIA API CAN? JQL seems like a great way to leverage your existing
SQL knowledge no compile time checking JPA Criteria API quiet a productivity drain with
developers having to correct, compile and redeploy to continue.
HOW TO USE THE JPA CRITIERA API
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cqry = em.createQuery();
A SIMPLE CRITERIAQUERY EXAMPLE
CriteriaBuilder cb = em.getCriteriaBuilder(); //Step 1
CriteriaQuery cqry = em.createQuery(); //Step 1 //Interesting stuff happens here Root<MyEntity> root = cqry.from(MyEntity.class); //Step 2 cqry.select(root); Step 3 …. Query qry = em.createQuery(cqry); //Step 6 List<MyEnity> results = qry.getResultList(); //Step 6
EXAMPLE CONTINUE… Root<MyEntity> root = cqry.from(MyEntity.class); //Step 2 cqry.select(root); //Step 3 Predicate pGtAge = cb.gt(root.get("age"),10); //Step 4 cqry.where(pGtAge); //Step 5
Root<MyEnity> root = cqry.from(MyEntity.class); //Step 2 cqry.select(root); //Step 3 Predicate pGtAge = cb.gt(root.get("age"),10); //Step 4 Predicate pGtDateCreated= cb.greaterThan(root.get("dateCreated"),date); //Step 4 Predicate pAnd = cb.and(pGtDateCreated,pGtAge); //Step 4
cqry.where(pAnd); //Step 5
USING META MODEL CLASSES IN QUERY
//assume we have created a date object for 2011-07-01 //called date Root<MyEnity> root = cqry.from(MyEntity.class); //Step 2 cqry.select(root); //Step 3 Predicate pGtAge = cb.gt(root.get(MyEntity_.age),10); //Step 4 Predicate pGtDateCreated= cb.greaterThan(root.get(MyEntity_.dateCreated),date); //Step 4 Predicate pAnd = cb.and(pGtDateCreated,pGtAge); //Step 4 cqry.where(pAnd); //Step 5
CRITERIA QUERY USING JOINS Root<MyEnity> root = cqry.from(MyEntity.class); //Step 2 Join<MyEntity,AnotherEntity> join = root.join(MyEntity_.anotherEntity); //Step 2 //Join<MyEntity,AnotherEntity> join = root.join("anotherEntity"); //Step 2 cqry.select(root); //Step 3 Predicate pGtAge = cb.gt(root.get(MyEntity_.age),10); //Step 4 Predicate pGtDateCreated= cb.greaterThan(root.get(MyEntity_.dateCreated),date); //Step 4 Predicate pEqEnabled = cb.equals(join.get(AnotherEntity_.enabled),false); Predicate pAnd = cb.and(pGtDateCreated,pGtAge,pEqEnabled); //Step 4 cqry.where(pAnd); //Step 5
MORE COMPLEX SELECT CLAUSE Root<MyEnity> root = cqry.from(MyEntity.class); //Step 2 cqry.select(root.get(MyEntity_.dateCreated)); //Step 3 If we wanted to use an aggregate function and get the minimum dateCreated we
could use something like: Root<MyEnity> root = cqry.from(MyEntity.class); //Step 2 Expression min = cb.min(root.get(MyEntity_.dateCreated));//Step3 cqry.select(min); //Step 3
REFERENCE http://www.oracle.com http://www.jumpingbean.co.za/blogs/jpa2-criteria-api
Q&A
Topic : JNDI Kaster Nurmukan
AGENDA What is JNDI? Naming and Directory Services Naming Concepts Issues JNDI Architecture Programming with JNDI Role of JNDI in J2EE
JNDI
332 (c)CDAC(Formerly NCST)
Class.forName("com.microsoft.jdbc. sqlserver.SQLServerDriver");
cnn = DriverManager.getConnection ("jdbc:microsoft:sqlserver://siddh ant:1433",“username",“password");
JNDI
333 (c)CDAC(Formerly NCST)
Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup(“myname”); Connection con = ds.getConnection(“abc”,”***”);
JNDI
334 (c)CDAC(Formerly NCST)
JNDI Java Naming and Directory Interface (JNDI) provides a
standard interface for Java applications to access naming and directory services.
JNDI
335 (c)CDAC(Formerly NCST)
NAMING SERVICE Naming Service performs: – Binding: Associating names with objects – Lookup: Find an object based on a name. • Examples: DNS and File systems Examples: – DNS – Filesystems
JNDI
336 (c)CDAC(Formerly NCST)
DIRECTORY SERVICE Directory is a naming service that stores objects with attributes. – Usernames and passwords etc stored in attrs. Tree like structure
JNDI
337 (c)CDAC(Formerly NCST)
NAMES Atomic name is a indivisible component of a name – in /etc/fstab, etc and fstab are atomic names. Compound name is zero or more atomic names put together. – /etc/fstab is a compound name
JNDI
338 (c)CDAC(Formerly NCST)
BINDING Binding is an association of a name with an
object. – Filename “autoexec.bat” has a binding to
some file data on the disk. – “c:\windows” foldername is bound to a
folder on your drive. Compound name such as
/usr/people/ed/.cshrc consists of multiple bindings, one to usr,
one to people, one to ed, and one to .cshrc.
JNDI
339 (c)CDAC(Formerly NCST)
CONTEXT Contains zero or more bindings. – Each binding has a distinct atomic name. /etc contains files named mtab and exports. The /etc folder is a context containing
bindings with atomic names mtab and exports.
mtab and exports are each bound to a file on the disk.
JNDI
340 (c)CDAC(Formerly NCST)
SUB-CONTEXT
/usr – CONTEXT – /usr/people – SUB-CONTEXT – /usr/bin – SUB-CONTEXT – /usr/local – SUB-CONTEXT Each atomic name is bound to a sub-context the
subfolder. Subcontext are full-fledged contexts Can contain more name-object bindings, such as
other files or other folders.
JNDI
341 (c)CDAC(Formerly NCST)
NAMING SYSTEM AND NAMESPACES Naming system: A connected set of contexts. Namespace: all the names contained within that naming system.
JNDI
342 (c)CDAC(Formerly NCST)
INITIALCONTEXT Starting point for exploring a namespace. Starting point for performing all naming and directory operations.
JNDI
343 (c)CDAC(Formerly NCST)
ISSUES Many naming and directory products. – Netscape Directory Server – MicrosoftActiveDirectory Various naming and directory protocols:
Each directory standard has a different protocol
for accessing the directory. – Lightweight Directory Access Protocol
(LDAP) – Network Information System (NIS) – Novell’s Network Directory System (NDS)
EDS h i’ API
JNDI
344 (c)CDAC(Formerly NCST)
INTRODUCING JNDI Standard interface to interact with naming and directory systems. For Java programs. Provides common interface to disparate directories: Same API for LDAP and NIS NDS. Used in EJB, RMI-IIOP, JDBC for operations
like locating entities i.e. Users, Machines (e.g.
printer), Objects, Services (e.g. datasource) etc.
JNDI
345 (c)CDAC(Formerly NCST)
JNDI ARCHITECTURE
The client API – Allow Java code to perform directory operations. The Service Provider: Driver The Service Provider Interface (SPI) – An interface to which naming and
directory service vendors can plug in.
JNDI
346 (c)CDAC(Formerly NCST)
JNDI
347 (c)CDAC(Formerly NCST)
JNDI PACKAGES The JNDI comprises of 5 packages javax.naming – Contains classes and
interfaces for accessing naming services javax.naming.directory – Extends
javax.naming and provides functionality to access directory services in addition to naming services
JNDI
348 (c)CDAC(Formerly NCST)
JNDI PACKAGES javax.naming.event – Classes and
interfaces for supporting event notification in naming and directory services
javax.naming.ldap – Classes and interfaces for using features that are specific to LDAP v3 that are not already covered by the more generic javax.naming.directory
javax.naming.spi – Vendors develop their naming/directory services conforming to SPI. Applications can then access these services through the JNDI API
JNDI
349 (c)CDAC(Formerly NCST)
INITIALCONTEXTFACTORY Used to acquire an initial context Implementation of the JNDI driver: Knows
the specific semantics of a particular directory structure. bootstrapping. Necessary information for JNDI to acquire
that initial context. – The IP address of the J2EE server – The port number that the J2EE server
accepts – Any username/password necessary to use
JNDI
350 (c)CDAC(Formerly NCST)
javax.naming.Context ctx = new javax.naming.InitialContext (System.getProperties()); java -Djava.naming.factory.initial= com.sun.jndi.fscontext.RefFSContextFactory -Djava.naming.provider.url= file:c:\examples.InitCtx class of the JNDI driver provider URL: URL that the service provider accepts for bootstrapping.
JNDI
351 (c)CDAC(Formerly NCST)
OTHER JNDI OPERATIONS Methods invoked on a Context list() - list of contents available at the
context. – names of objects bound to the JNDI tree – subcontexts. lookup() - look up objects bound to the JNDI
tree – Return type is driver specific • RMI-IIOP java.rmi.Remote • file system java.io.File
JNDI
352 (c)CDAC(Formerly NCST)
rename() - give a new name to a context – c:\temp to c:\tmp createSubcontext() - create a subcontext at the context – c:\foo\bar at the folder c:\foo. destroySubcontext() - destroy a subcontext of
the context – Destroy c:\foo\bar from the folder c:\foo. bind() – associates a name to a content and
stores it at the Context – JNDI drivers accept different parameters to
bind() rebind() - forces a bind even if some object is
JNDI
353 (c)CDAC(Formerly NCST)
BINDING import javax.naming.*; public class Startup { public static void main(String args[]) throws
Exception { AccountImpl acct_impl = new AccountImpl(); Context ctx = new InitialContext
(System.getProperties()); ctx.rebind(“myname", acct_impl); } }
JNDI
354 (c)CDAC(Formerly NCST)
LOOKING UP import javax.naming.*; import java.rmi.*; public class Client { public static void main (String[] args) throws
Exception { Context ctx = new InitialContext (System.getProperties());
Object remoteObject = ctx.lookup(“myname"); Account account = (Account) javax.rmi.PortableRemoteObject.narrow ( remoteObject, Account.class); int b = account.method1(5));}}
JNDI
355 (c)CDAC(Formerly NCST)
ROLE OF JNDI IN J2EE J2EE servers have a JNDI implementation. Used to Look up beans. Connect to resource factories – JDBC DataSource – Java Message Service (JMS) drivers Acquiring a reference to the Java Transaction API’s (JTA) UserTransaction interface.
JNDI
356 (c)CDAC(Formerly NCST)
REFERENCES Mastering Enterprise JavaBeans by Ed Roman et. al. (Wiley) JNDI Tutorial on java.sun.com Java Server Programming J2EE Edition – Volume 1 – Wrox. Java Enterprise in a nutshell – David Flanagan et. Al. – O’reilly
JNDI
357 (c)CDAC(Formerly NCST)
Q&A
Topic : EJB Kaster Nurmukan
ENTERPRISE JAVA BEANS (EJB)
360
EJB GOALS Standard component architecture for building
distributed business applications in Java Interoperability between enterprise beans and
other Java Platform Enterprise Edition components, as well as non-Java applications
Compatible with other Java APIs and with CORBA protocols
Follow the Write Once, Run Anywhere philosophy of Java - an enterprise bean can be developed once and then deployed on multiple platforms without recompilation or source code modification
Define the “contracts” that enable tools from multiple vendors to develop and deploy components that can interoperate at runtime
361
REPRISE: 3-TIERED ARCHITECTURE
362
Client
Database
Component middleware
Application logic components
Back-end tier
Middle tier
Front-end tier
LDAP Database
Client
Database
Component middleware
Application logic components
Back-end tier
Middle tier
Front-end tier
LDAP Database
EJB 3-TIERED ARCHITECTURE
363
Client
Database
Component middleware
Application logic components
Back-end tier
Middle tier
Front-end tier
LDAP Database
Application server
EJBs
JAVA EE 3-TIER ARCHITECTURE
364
EJBS AS COMPONENTS Enterprise Java Beans are components that provide
middle-tier business logic And interact heavily with the data layer of the
application EJB framework conforms to and at the same time
induces a 3-tier architecture for distributed applications
365
EJB AS COMPONENT MODEL FRAMEWORK
Programming model Standardized interfaces Runtime environment Built-in component services (persistence, transactions,
security, etc.) Meta-data Deployment facilities
366
EJB SPECIFICATION EJB is an open specification - any vendor can develop a
runtime environment that complies with the specification
EJB code intended to be portable across brands (assuming uses only services defined by the spec, not additional vendor facilities)
EJB specs have evolved: Originated with IBM 1997 Later adopted by Sun (1.0 1998, 1.1 1999) Enhanced under Java community process (2.0 2001,
2.1 2003, 3.0 2006) EJB 3.0 is a major departure from earlier versions, but
backwards compatible (old code works with 3.0 but not vice versa)
367
ENTERPRISE BEANS Body of code with fields and methods Encapsulates business data or business logic that
operates on the enterprise’s data Instances are created and managed at runtime by a
Container (application server) Client access is mediated by the bean instance’s
Container - isolates the bean from direct access by client applications (and other beans)
368
ENTERPRISE BEAN PORTABILITY If an enterprise bean uses only the services defined by the EJB specification (and not additional facilities peculiar to the vendor), the bean can be deployed in any compliant EJB Container
Can be included in an assembled application without requiring source code changes or recompilation
Component services information, such as a transaction and security attributes, are separate from the enterprise bean class - this allows the services information to be managed by tools during application assembly and deployment
Can be customized at deployment time by editing the bean’s environment entries and/or deployment descriptor
369
EJB CONTAINER Manages every aspect of an enterprise bean at runtime
and implements component services When a client application invokes a method on an
enterprise bean, the container first intercepts the invocation to ensure persistence, transactions and access control are applied properly to every operation a client performs on the bean
An enterprise bean cannot function outside of an EJB container
370
EJB CONTAINER
371
RESOURCE MANAGEMENT Containers manage many beans simultaneously To reduce memory consumption and processing,
containers pool resources When a bean is not being used, a container may
place it in a pool to be reused by another client Or evict it from memory (passivate) and only bring
it back (activate) when its needed While its reference on the client remains intact When the client invokes a method on the reference,
the container re-incarnates the bean to service the request
372
BUSINESS DATA AND METHODS An entity bean (aka persistence entity)
represents persistent business data stored in one row of a database table, and may add behavior specific to that data - but the methods are often just getters, setters and finders
Session beans implement business processes and interact with clients
Message-driven beans combine features of a session bean and a message listener, allowing a business component to receive messages (and event notifications) asynchronously
373
BUSINESS INTERFACES A “business interface” is required for both session and
message-driven beans (and for entities prior to EJB 3.0) The business interface of a message-driven bean is
defined by the messaging type used (typically MessageListener), not by the developer
374
MULTIPLE INTERFACES If a bean class implements only a single interface (not counting
standard interfaces such as java.io.Serializable or any of the javax.ejb interfaces), it is deemed the “business interface” and is by default a local interface unless designated by a @Remote annotation
A bean class may have multiple interfaces, but one or more must be designated as a business interface by either a @Local or @Remote annotation
Remote business interfaces support remote clients running on a different JVM or machine, to which the bean’s location is transparent
If there are only local interfaces, all clients must run in the same JVM as the bean, and the location of the bean is not transparent 375
EXAMPLE @Stateless @Remote public class CalculatorBean implements Calculator { public float add (int a, int b) { return a + b; } public float subtract (int a, int b) { return a - b; } } public interface Calculator { public float add (int a, int b); public float subtract (int a, int b); }
376
REMOTE AND LOCAL INTERFACES To allow remote access, must decorate the business interface with
the @Remote annotation @Remote public interface InterfaceName { ... }
OR decorate the bean class with @Remote, specifying the business interface(s) @Remote(InterfaceName.class) public class BeanName
implements InterfaceName { ... } To build an enterprise bean that allows only local access,
optionally annotate the business interface of the enterprise bean as @Local @Local public interface InterfaceName { ... }
OR specify the interface by decorating the bean class with @Local and specify the interface name @Local(InterfaceName.class) public class BeanName
implements InterfaceName { ... }
377
ENTERPRISE BEANS AS DISTRIBUTED OBJECTS Business interfaces are types of Java RMI
Remote interfaces The java.rmi.Remote interface is used by
distributed objects to represent the bean in a different address space (process or machine)
An enterprise bean class is instantiated and lives in its container but can be accessed by client applications that live in other address spaces, using skeletons and stubs implemented by the container
378
STUBS AND SKELETONS
September 16, 2010
379
COM
S W4156
DECIDING ON LOCAL VS. REMOTE: COUPLING Tightly coupled beans depend on one another For example, if a session bean that processes sales
orders calls a session bean that emails a confirmation message to the customer, these beans are tightly coupled
Tightly coupled beans are good candidates for local access
Because they fit together as a logical unit, they typically call each other often and would benefit from the increased performance that is possible with local access
380
DECIDING ON LOCAL VS. REMOTE: TYPE OF CLIENT
If an enterprise bean is accessed by application clients, then it should allow remote access
In a production environment, these clients almost always run on different machines than the Application Server
If an enterprise bean’s clients are web components or other enterprise beans, then the type of access depends on how you want to distribute your components
381
DECIDING ON LOCAL VS. REMOTE: COMPONENT DISTRIBUTION
Java EE applications are scalable because their server-side components can be distributed across multiple machines
In a distributed application, the web components may run on a different server than do the enterprise beans they access
Then the enterprise beans should allow remote access
382
PERFORMANCE
Due to factors such as network latency, remote calls are often slower than local calls
On the other hand, if you distribute components among different servers, you may improve the application’s overall performance
Actual performance can vary in different operational environments
383
DECIDING ON LOCAL VS. REMOTE If you aren’t sure which type of access an
enterprise bean should have, choose remote access, which gives more flexibility
In the future you can distribute your components to accommodate the growing demands on your application
It is possible for an enterprise bean to allow both remote and local access through different interfaces (the same business interface cannot be both a local and remote business interface)
384
SESSION BEANS
385
SESSION BEAN Represents a single client (at a time) inside the
Application Server Client invokes the session bean’s methods to execute
business tasks When the client terminates, the session bean appears to
have terminated and is no longer associated with the client
386
STATEFUL VS. STATELESS There are two basic kinds of session bean:
Stateless and Stateful Stateful session beans encapsulate business
logic and state specific to a client Stateful beans are called "stateful" because they
maintain conversational state between method invocations
The state is held in instance variables (in memory) and is not persistent across executions
The state disappears when the client removes the bean or terminates
387
STATEFUL SESSION BEANS To conserve resources, stateful session beans may be
passivated when not in use by the client Passivation means the bean's conversational-state is
written to secondary storage (disk) and the instance is removed from memory
If the client removes the bean or terminates, the session ends and the state disappears
The client's reference to the bean is not affected by passivation: it remains alive and usable while the bean is passivated
When the client invokes a method on a bean that is passivated, the container will activate the bean by instantiating a new instance and populating its conversational-state with the state previously written to secondary storage
388
STATELESS VS. STATEFUL Stateless session beans are made up of
business methods that behave like functions: they operate only on the arguments passed to them when they are invoked (but can lookup state in a database or file)
Stateless beans are called "stateless" because they are transient - they do not maintain a conversational state between method invocations
The bean’s instance variables may contain a state specific to the client during a single method invocation, but not retained when the method is finished
389
STATELESS SESSION BEANS Each invocation of a stateless business method is
independent from previous invocations Because stateless session beans are "stateless" they
tend to process requests faster and use less resources All instances are equivalent – the EJB container can
assign a pooled stateless bean instance to any client, improving scalability
September 16, 2010
390
COM
S W4156
SESSION BEAN INTERFACES A client can access a session bean only through
the methods in the bean’s business interface Can have more than one business interface A business interface can be either local or
remote (or web service) Not required to implement any lifecycle
methods, but may optionally do so and annotate as such (prior to EJB 3.0, all enterprise beans had to implement a “home” interface with lifecycle methods)
391
LIFECYCLE METHODS The actual methods can have any names @PostConstruct: The container immediately calls
the annotated method after a bean instance is instantiated
@Init: Designates initialization methods for a stateful session bean
@PrePassivate: Called before the container passivates a stateful bean instance
@PostActivate: Called when a re-activated stateful bean instance is ready
@Remove: Informs the container to remove the bean instance from the object pool after the method executes (not actually a callback)
@PreDestroy: Called before the container destroys an unused or expired bean instance from its object pool
392
LIFECYCLE OF A STATEFUL SESSION BEAN Client initiates the lifecycle by obtaining a reference Container invokes the @PostConstruct and @Init
methods, if any Now bean ready for client to invoke business methods
393
LIFECYCLE OF A STATEFUL SESSION BEAN While in ready state, container may passivate and
invoke the @PrePassivate method, if any If a client then invokes a business method, the
container invokes the @PostActivate method, if any, and it returns to ready stage
394
LIFECYCLE OF A STATEFUL SESSION BEAN At the end of the life cycle, the client invokes a method
annotated @Remove The container calls the @PreDestroy method, if any
395
LIFECYCLE OF A STATELESS SESSION BEAN A client initiates the life cycle by obtaining a reference The container invokes the @PostConstruct method, if
any The bean is now ready to have its business methods
invoked by clients
396
LIFECYCLE OF A STATELESS SESSION BEAN Because a stateless session bean is never passivated, its
life cycle has only two stages: nonexistent and ready for the invocation of business methods.
At the end of the life cycle, the container calls the @PreDestroy method, if any
397
ENTITY BEANS
398
ENTITY BEANS Called entity beans < EJB 3.0, persistence
entities (or just entities) >= EJB 3.0 Provides an object view of data in the database
An entity class represents a table in a relational database
An entity instance represents a row in that table Uses the Java Persistence API Annotated with @Entity
399
ENTITY BEANS An entity bean provides an object view of data in
the database Allows shared access from multiple users Can be long-lived (as long as data in the database) Persistent
The entity and its remote reference survive a crash of the EJB Container
If the state of an entity was being updated by a transaction at the time the container crashed, the entity’s state is automatically reset to the state of the last committed transaction
An application program can create an entity bean, then be stopped and restarted, and again find the entity bean it was working with - and continue using the same entity bean 400
INSTANCE VARIABLES Persistent instance variables can only be accessed
through the entity class’ methods Must only be serializable types (so they can be stored in
a database) Object/relational mapping must be defined An entity may include non-persistent instance
variables, annotated as @Transient
401
ENTITY BEANS ARE IDENTIFIED BY A PRIMARY KEY Entity Beans must have a primary key that
uniquely identifies it Used to locate the bean’s data in some
underlying database For example, an “employee” entity bean may
have a Social Security number as primary key You can only use entity beans when your
objects have a unique identifier field, or when you can add such a field (or set of fields)
402
PRIMARY KEYS May be either simple or composite Simple primary keys annotated @Id Composite primary keys defined by a primary
key class, annotated @IdClass The simple primary key, or each field of a
composite primary key, must be a Java primitive type, string or date
EntityManager.find method used to look up entities by primary key, returns reference to the one specific entity bean (exception if not found)
403
QUERIES Other finder methods defined using SQL-like queries in Java Persistence Query Language, return a collection of entities that match the request
EntityManager.createQuery method used to create dynamic queries defined within business logic public List findWithName(String name) { return em.createQuery( "SELECT c FROM Customer c WHERE c.name LIKE :custName")
.setParameter("custName", name) .setMaxResults(10) .getResultList(); }
404
QUERIES EntityManager.createNamedQuery method used to create static queries defined in annotation metadata @NamedQuery( name="findAllCustomersWithName", query="SELECT c FROM Customer c WHERE c.name LIKE :custName"
) customers = em.createNamedQuery("findAllCustomersWithName")
.setParameter("custName", "Smith") .getResultList();
405
MANAGING ENTITIES An Entity Manager is associated with a
persistence context corresponding to a particular data store
State of persistent entities automatically synchronized to the database when the associated transaction commits
But business logic for transactions resides in session or message-driven beans
Both Container-Managed Entity Managers (automatic) and Application-Managed Entity Managers
406
CONTAINER-MANAGED TRANSACTIONS Container sets the boundaries of transactions,
cannot use operations like commit or rollback within code
Container begins transaction immediately before enterprise bean method starts and commits just before method exits
Transaction types: Required, RequiresNew, Mandatory, NotSupported, Supports, Never
407
TRANSACTIONAL ATTRIBUTES Required - If the client is running within a transaction and invokes the
enterprise bean's method, the method executes within the client's transaction. If the client is not associated with a transaction, the container starts a new transaction before running the method.
RequiresNew - If the client is running within a transaction and invokes the enterprise bean's method, the container suspends the client's transaction, starts a new transaction, delegates the call to the method, resumes the client's transaction after the method completes; if the client is not associated with a transaction, the container starts a new transaction before running the method.
NotSupported - If the client is running within a transaction and invokes the enterprise bean's method, the container suspends the client's transaction before invoking the method; after the method has completed, the container resumes the client's transaction.
Supports - If the client is running within a transaction and invokes the enterprise bean's method, the method executes within the client's transaction; if the client is not associated with a transaction, the container does not start a new transaction before running the method
Mandatory - If the client is running within a transaction and invokes the enterprise bean's method, the method executes within the client's transaction; if the client is not associated with a transaction, the container throws the TransactionRequiredException.
Never - If the client is running within a transaction and invokes the enterprise bean's method, the container throws a RemoteException
408
APPLICATION-MANAGED TRANSACTIONS The code in the session or message-driven bean
explicitly marks the boundaries of the transaction Useful for implementing multiple transactions within a
single method or transactions than span multiple methods
Can use either Java Database Connectivity (JDBC) or the Java Transaction API (JTA)
A JTA transaction can span updates to multiple databases from different vendors managed by the Java Transaction Service, but cannot support nested transactions
JTA supplies begin, commit and rollback methods 409
USING TRANSACTIONS IN SESSION BEANS A stateless session bean with bean-managed
transactions must commit or rollback before returning
A stateful session bean using JTA transactions retains its association with a transaction across multiple client calls, even if the database connection is opened and closed
A stateful session bean using JDBC transactions loses its transaction association if the connection is closed
410
SAVING A SESSION BEAN’S STATE IN A DATABASE Transactions normally concerned with
synchronizing the state of persistent entities to databases
Optional for a stateful session bean to receive transaction synchronization notifications to also store its own data in a database
Then must implement the SessionSynchronization interface, supplying afterBegin, beforeCompletion and afterCompletion methods
411
Q&A
MESSAGE-DRIVEN BEAN(MDB)
413
GOALS Be able to produce messages from the EJB server Be able to consume messages within the EJB
server Be able to define timers within EJB server
v131202
414
Asynchronous EJB
OBJECTIVES EJB JMS Producers EJB JMS Consumers (Message Driven Beans;
MDBs) Asynchronous Methods EJB Timers
v131202
415
Asynchronous EJB
415
EJB JMS PRODUCERS Obtain Resources
ConnectionFactory Destination
Create Session integrate with JTA transaction
Publish Message
v131202
416
Asynchronous EJB
416
OBTAINING A CONNECTIONFACTORY Using annotations
@Stateless
public class SellerEJB ... {
@Resource(mappedName=“java:/JmsXA")
private ConnectionFactory connFactory;
mappedName points to global JNDI name benefits
concise & simple
drawbacks mixes deployment concepts with Java code
v131202
417
Asynchronous EJB
417
OBTAINING A CONNECTIONFACTORY (CONT.) Using ejb-jar.xml
<ejb-name>SellerEJB</ejb-name>
<resource-ref>
<res-ref-name>jms/ConnectionFactory</res-ref-name>
<res-type>javax.jms.ConnectionFactory</res-type>
<mapped-name>java:/JmsXA</mapped-name>
<injection-target>
<injection-target-class>
ejava.examples.asyncmarket.ejb.SellerEJB
</injection-target-class>
<injection-target-name>
connFactory
</injection-target-name>
</injection-target>
</resource-ref>
...
mappedName moved away from code to DD factory injected into EJB ejb-jar xml is no longer vendor/deployment-neutral
v131202
418
Asynchronous EJB
418
OBTAINING A CONNECTIONFACTORY (CONT.) Using jboss-ejb3.xml
<session>
<ejb-name>SellerEJB</ejb-name>
<resource-ref>
<res-ref-name>jms/ConnectionFactory</res-ref-name>
<jndi-name>java:/JmsXA</jndi-name>
</resource-ref>
</session>
mappedName is now removed
replaced with vendor/deployment specific reference Required 3 files to complete
v131202
419
Asynchronous EJB
v111128 Asynchronous EJB 419
OBTAINING A DESTINATION Using annotations
@Stateless
public class SellerEJB implements SellerLocal, SellerRemote {
...
@Resource(mappedName="java:/topic/ejava/examples/asyncMarket/topic1",
type=Topic.class)
private Destination sellTopic;
mappedName points to global JNDI entry benefits
concise and simple drawbacks
mixes deployment properties with implementation
v131202
420
Asynchronous EJB
v111128 Asynchronous EJB 420
OBTAINING A DESTINATION (CONT.) Using ejb-jar.xml
<resource-env-ref>
<resource-env-ref-name>jms/sellTopic</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
<mapped-name>topic/ejava/examples/asyncMarket/topic</mapped-name>
<injection-target>
<injection-target-class>
ejava.examples.asyncmarket.ejb.SellerEJB
</injection-target-class>
<injection-target-name>sellTopic</injection-target-name>
</injection-target>
</resource-env-ref>
mappedName moved away from Java and to DD note resource-env-ref used for Destinations
v131202
421
Asynchronous EJB
v111128 Asynchronous EJB 421
GETTING A SESSION @TransactionAttribute(TransactionAttributeType.REQUIRED)
public long sellProduct(String sellerId, AuctionItem item)
throws MarketException {
Connection connection = null;
Session session = null;
try {
connection = connFactory.createConnection();
session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
...
}
catch (JMSException ex) {
log.error("error publishing sell", ex);
ctx.setRollbackOnly();
throw new EJBException("error publishing sell:" + ex);
}
finally {
try {
if (session != null) { session.close(); }
if (connection != null) { connection.close(); }
} catch (JMSException ex) {
v131202
422
Asynchronous EJB
422
INTEGRATING JMS INTO THE TRANSACTION Person seller = sellerDAO.getPersonByUserId(sellerId); seller.getItems().add(item);
item.setOwner(seller);
auctionItemDAO.createItem(item);
publishForSale(session, item);
return item.getId();
v131202
423
Asynchronous EJB
423
PUBLISHING THE MESSAGE protected void publishForSale(Session session, AuctionItem item) throws JMSException {
MessageProducer producer = null;
try {
producer = session.createProducer(sellTopic);
MapMessage message = session.createMapMessage();
message.setJMSType("forSale");
message.setLong("id", item.getId());
message.setString("name", item.getName());
message.setString("seller", item.getOwner().getUserId());
message.setLong("startDate", item.getStartDate().getTime());
message.setLong("endDate", item.getEndDate().getTime());
message.setDouble("minBid", item.getMinBid());
message.setDouble("bids", item.getBids().size());
message.setDouble("highestBid",
(item.getHighestBid() == null ? 0.00 :
item.getHighestBid().getAmount()));
producer.send(message);
}
finally {
v131202
424
Asynchronous EJB
424
EJB JMS CONSUMERS; MDBS “Message Driven Bean” Introduced in EJB 2.0 to support JMS providers Extended in EJB 2.1 to support non-JMS
message providers using the Java EE Connector API
commonly called JCA EJB 3.0 added @Annotation support for
configuration Java EE Providers
must support a JMS provider must support external providers through JCA
Session and Entity Beans cannot be a MessageListener can poll for messages with
MessageConsumer receive()
v131202
425
Asynchronous EJB
425
MESSAGEDRIVEN BEAN CONFIGURATION Destination Type Destination Selector Message Acknowledgement ...
v131202
426
Asynchronous EJB
426
MDB CONFIGURATION Using annotations
@MessageDriven(name="BuyerMDB", activationConfig={
@ActivationConfigProperty(
propertyName="destinationType",
propertyValue="javax.jms.Topic"),
@ActivationConfigProperty(
propertyName="destination",
propertyValue="topic/ejava/.../topic1"),
@ActivationConfigProperty(
propertyName="messageSelector",
propertyValue=
"JMSType in ('forSale', 'saleUpdate')"),
@ActivationConfigProperty(
propertyName="acknowledgeMode",
propertyValue="Auto-acknowledge")
})
public class BuyerMDB implements MessageListener {
v131202
427
Asynchronous EJB
427
MDB CONFIGURATION (CONT.) Using ejb-jar.xml
<message-driven>
<ejb-name>BuyerMDB</ejb-name>
<ejb-class>ejava.examples.asyncmarket.ejb.BuyerMDB</ejb-class>
<message-destination-type>
javax.jms.Topic
</message-destination-type>
<activation-config>
<activation-config-property>
<activation-config-property-name>
...
</activation-config-property-name>
<activation-config-property-value>
...
</activation-config-property-value>
</activation-config-property>
</activation-config>
v131202
428
Asynchronous EJB
428
MDB CONFIGURATION (CONT.) Using jboss.xml
<message-driven>
<ejb-name>BuyerMDB</ejb-name>
<destination-jndi-name>
topic/ejava/examples/asyncMarket/topic1
</destination-jndi-name>
429
Asynchronous EJB
v111128 429
MDB STRUCTURE @MessageDriven(name="BuyerMDB", activationConfig={ ... })
public class BuyerMDB implements MessageListener {
@PostConstruct
public void init() { ... }
public void onMessage(Message message) {
try {
log.debug("onMessage:" + message.getJMSMessageID());
MapMessage auctionMsg = (MapMessage)message;
long itemId = auctionMsg.getLong("id");
processAuctionItem(itemId);
}
catch (Exception ex) {
log.error("error processing message", ex);
}
}
430
MDB AND TRANSACTIONS SUPPORTED
message receipt/acknowledgement integrated with overall transaction
NOT_SUPPORTED message receipt/acknowledgement independent of
transactions within processing
431
Asynchronous EJB
v111128 431
ASYNCHRONOUS METHODS • Scenario
– Task(s) may take considerable time to complete – Client need not wait for them to complete
• @javax.ejb.Asynchronous – Return control to the client before EJB is invoked – Any session bean business method may be made
@Asynchronous* (*see Serialization note below) • null return type
– Client and issued task fully decoupled from one another • java.util.concurrent.Future return type
– Allows task and client to coordinate a future return value – Client returns instance of javax.ejb.AsyncResult – Not Serializable (i.e., cannot use directly with RMI client)
432
SYNCHRONOUS EXAMPLE: CLIENT EJB @Stateless
public class AuctionMgmtEJB implements AuctionMgmtRemote, AuctionMgmtLocal { private @EJB AuctionMgmtActionEJB actions;
public void workSync(int count, long delay) {
DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
long startTime = System.currentTimeMillis();
for (int i=0; i<count; i++) {
log.info(String.format("%s issuing sync request, delay=%d",
df.format(new Date()), delay));
Date date= actions.doWorkSync(delay);
log.info(String.format("sync waitTime=%d msecs",
System.currentTimeMillis()-startTime));
}
long syncTime = System.currentTimeMillis() - startTime;
log.info(String.format("workSync time=%d msecs", syncTime));
}
433
SYNCHRONOUS EXAMPLE: HELPER EJB @Stateless
public class AuctionMgmtActionEJB {
public Date doWorkSync(long delay) {
DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
log.debug(String.format("sync method %d starting %d delay at %s",
Thread.currentThread().getId(), delay, df.format(new Date())));
try { Thread.sleep(delay); }
catch (Exception ex) { ... }
Date now = new Date();
log.debug(String.format("sync method %d completed %d delay at %s",
Thread.currentThread().getId(), delay, df.format(now)));
return now;
}
434
SYNCHRONOUS EXAMPLE: RESULTS 11:06:44,624 INFO [AuctionMgmtEJB:306] 11:06:44.612 issuing sync request, delay=3000 11:06:44,626 DEBUG [AuctionMgmtActionEJB:24] sync method 163 starting 3000 delay at 11:06:44.626 11:06:47,628 DEBUG [AuctionMgmtActionEJB:30] sync method 163 completed 3000 delay at 11:06:47,630 INFO [AuctionMgmtEJB:309] sync waitTime=3018 msecs 11:06:47,631 INFO [AuctionMgmtEJB:306] 11:06:47.631 issuing sync request, delay=3000 11:06:47,634 DEBUG [AuctionMgmtActionEJB:24] sync method 163 starting 3000 delay at 11:06:47.634 11:06:50,636 DEBUG [AuctionMgmtActionEJB:30] sync method 163 completed 3000 delay at 11:06:50,637 INFO [AuctionMgmtEJB:309] sync waitTime=6025 msecs 11:06:50,637 INFO [AuctionMgmtEJB:306] 11:06:50.637 issuing sync request, delay=3000 11:06:50,638 DEBUG [AuctionMgmtActionEJB:24] sync method 163 starting 3000 delay at 11:06:50.638 11:06:53,640 DEBUG [AuctionMgmtActionEJB:30] sync method 163 completed 3000 delay at 11:06:53.640 11:06:53,641 INFO [AuctionMgmtEJB:309] sync waitTime=9029 msecs 11:06:53 642 INFO [AuctionMgmtEJB:312] workSync time=9030 msecs
435
ASYNCHRONOUS EXAMPLE: CLIENT EJB @Stateless
public class AuctionMgmtEJB implements AuctionMgmtRemote, AuctionMgmtLocal {
public void workAsync(int count, long delay) {
DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
long startTime = System.currentTimeMillis();
List<Future<Date>> results = new ArrayList<Future<Date>>();
for (int i=0; i<count; i++) {
log.info(String.format("%s issuing async request,
delay=%d", df.format(new Date()), delay));
Future<Date> date = actions.doWorkAsync(delay);
results.add(date);
log.info(String.format("async waitTime=%d msecs",
System.currentTimeMillis()-startTime));
}
for (Future<Date> f: results) {
log.info(String.format("%s getting async response",
df.format(new Date())));
try { Date date = f.get(); } catch (Exception ex) {
throw new EJBException("unexpected error in future get():"+ex);}
436
ASYNCHRONOUS EXAMPLE: HELPER EJB @Stateless
public class AuctionMgmtActionEJB {
@javax.ejb.Asynchronous
public java.util.concurrent.Future<Date> doWorkAsync(long delay) {
DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
log.debug(String.format("async method %d starting %d delay at %s",
Thread.currentThread().getId(), delay, df.format(new Date())));
try { Thread.sleep(delay); }
catch (Exception ex) { ... }
Date now = new Date();
log.debug(String.format("async method %d completed %d delay at %s",
Thread.currentThread().getId(), delay, df.format(now)));
return new javax.ejb.AsyncResult<Date>(now);
}
437
ASYNCHRONOUS EXAMPLE: RESULTS 11:06:53,650 INFO [AuctionMgmtEJB:325] 11:06:53.650 issuing async request, delay=3000 11:06:53,658 INFO [AuctionMgmtEJB:328] async waitTime=8 msecs 11:06:53,659 INFO [AuctionMgmtEJB:325] 11:06:53.659 issuing async request, delay=3000 11:06:53,659 DEBUG [AuctionMgmtActionEJB:41] async method 166 starting 3000 delay at 11:06:53.659 11:06:53,668 DEBUG [AuctionMgmtActionEJB:41] async method 167 starting 3000 delay at 11:06:53.668 11:06:53,668 INFO [AuctionMgmtEJB:328] async waitTime=18 msecs 11:06:53,669 INFO [AuctionMgmtEJB:325] 11:06:53.669 issuing async request, delay=3000 11:06:53,670 INFO [AuctionMgmtEJB:328] async waitTime=20 msecs 11:06:53,670 DEBUG [AuctionMgmtActionEJB:41] async method 168 starting 3000 delay at 11:06:53.670 11:06:53,671 INFO [AuctionMgmtEJB:331] 11:06:53.671 getting async response 11:06:56,667 DEBUG [AuctionMgmtActionEJB:47] async method 166 completed 3000 delay at 11:06:56,669 DEBUG [AuctionMgmtActionEJB:47] async method 167 completed 3000 delay at 11:06:56,669 INFO [AuctionMgmtEJB:339] 11:06:56.669 got async response 11:06:56 670 INFO [AuctionMgmtEJB:331] 11:06:56 670 getting async response
438
EJB TIMERS Performs similar role of job schedulers
“cron” Two types
Single-action createTimer(Date expiration, Serializable info) fires once at or after a specific time in the future
createTimer(long duration, Serializable info) fires once after a specific delay period
Interval-timer createTimer(Date intialExpiration, long intervalDuration, Serializable info) continually fires every intervalDuration after the
initialExpiration time createTimer(long initialDuration, long intervalDuration, Serializable info) continually fires every intervalDuration after the
initialDuration delay
v131202
439
Asynchronous EJB
439
EJB TIMERS Original EJB Timer Service part of EJB 2.1 EJB 3.0 added annotation-based extensions that
eliminated inheritance-based solution requirements
EJB 3.1 provided an overhaul of the overall service Added declarative scheduling
@javax.ejb.ScheduleExpression @javax.ejb.Schedule
440
DECLARATIVE CALENDAR TIMER @Schedule(second="*/10", minute ="*", hour="*",
dayOfMonth="*", month="*", year="*”, persistent=false)
public void execute(Timer timer) {
log.info("timer fired:" + timer);
try {
checkAuction();
}
catch (Exception ex) {
log.error("error checking auction", ex);
}
}
441
PROGRAMMATIC CALENDAR TIMER ScheduleExpression schedule = new ScheduleExpression();
schedule.second("*/10");
schedule.minute("*");
schedule.hour("*");
schedule.dayOfMonth("*");
schedule.month("*");
schedule.year("*");
auctionMgmt.initTimers(schedule);
public void initTimers(ScheduleExpression schedule) {
cancelTimers();
log.debug("initializing timers, schedule="+schedule);
timerService.createCalendarTimer(schedule);
}
@Timeout
public void execute(Timer timer) {
log.info("timer fired:" + timer);
try {
checkAuction();
442
PROGRAMMATIC INTERVAL TIMER auctionMgmt.initTimers(10*1000);
public void initTimers(long delay) {
cancelTimers();
log.debug("initializing timers, checkItemInterval="+delay);
timerService.createTimer(0,delay, "checkAuctionTimer");
}
@Timeout
public void execute(Timer timer) {
log.info("timer fired:" + timer);
try {
checkAuction();
}
catch (Exception ex) {
log.error("error checking auction", ex);
443
EJB TIMERS Accessing TimerService
Using Annotations @Resource private TimerService timerService;
Getting Timers timerService.getTimers()
Cancelling Timers for (Timer timer :
(Collection<Timer>)timerService.getTimers()) {
timer.cancel();
}
Timers associated with the EJB that created them are automatically integrated into JTA transaction 444
EJB TIMER CALLBACKS Using annotations
public class AuctionMgmtEJB ... @Timeout public void execute(Timer timer) { try { checkAuction(); } catch (Exception ex) { log.error("error checking auction", ex); } }
Using interfaces public class AuctionMgmtEJB implements TimedObject, ...
public void ejbTimeout(Timer timer) { ... } }
445
JAVAX.EJB.TIMERSERVICE public interface javax.ejb.TimerService{
javax.ejb.Timer createTimer(long, java.io.Serializable) throws ...;
javax.ejb.Timer createSingleActionTimer(long, javax.ejb.TimerConfig)
throws ...;
javax.ejb.Timer createTimer(long, long, java.io.Serializable) throws ...;
javax.ejb.Timer createIntervalTimer(long, long, javax.ejb.TimerConfig)
throws ...;
javax.ejb.Timer createTimer(java.util.Date, java.io.Serializable) throws ...;
javax.ejb.Timer createSingleActionTimer(java.util.Date, javax.ejb.TimerConfig)
throws ...;
javax.ejb.Timer createTimer(java.util.Date, long, java.io.Serializable)
throws ...;
javax.ejb.Timer createIntervalTimer(java.util.Date, long,javax.ejb.TimerConfig)
throws ...;
javax.ejb.Timer createCalendarTimer(javax.ejb.ScheduleExpression) throws ...;
javax.ejb.Timer createCalendarTimer(javax.ejb.ScheduleExpression,
javax.ejb.TimerConfig) throws ...;
java util Collection getTimers() throws ;
446
SUMMARY EJB JMS Publishers
integrates into Session and MDB processing EJB JMS Subscriber
implemented using MDB MDBs support more than JMS using JCA
Asynchronous Methods EJB Timers
schedule re-activation of Session Bean Single-action and interval
v131202
447
Asynchronous EJB
447
REFERENCES Java Messaging Service API
http://java.sun.com/javaee/5/docs/api/javax/jms/package-summary.html
“Enterprise JavaBeans 3.0, 5th Edition”; Burke & Monsen-Haefel; ISBN 0-596-00978-X; O'Reilly
448