Académique Documents
Professionnel Documents
Culture Documents
0
Created 03/15/08
Updated 03/20/08, Updated 04/04/08, Updated 04/25/08, Updated 05/12/08, Updated 05/19/08, Updated 05/27/08
Updated 06/08/08, Updated 06/15/08, Updated 06/27/08, Updated 07/12/08, Updated 07/20/08, Updated 08/02/08
Updated 09/08/08, Updated 08/11/08, Updated 12/17/08, Updated 02/25/09, Updated 02/28/09, Updated 03/23/09
Updated 03/26/09, Updated 05/31/09, Updated 08/22/09, Updated 09/14/09
Introduction
These notes cover usage of the JBoss Application Server and the most important specification that it implements:
EJB 3.0. JBoss is a software product, and EJB3.0 is part of a larger specification called Java EE 5.0. EJB 3.0
focuses on the services that support back-end business logic and persistence, while Java EE 5.0 includes
specifications for presentation tools, security, web services, JMS, and more.
The JBoss Application Server is the latest in a series of releases of a J2EE-compliant application server. It dates
back to around 2001-2002, and has been greatly improved each year. Basically, an application server like this
provides the following:
Database connection management
Persistence management
Component development (the components are called Enterprise Java Beans)
Transaction Management
Security Management
Web Servlet Support
Clustering and Fail-Over Support
Other J2EE interfaces and standards, including JMS, JavaMail, Java Web Services, and more
JBoss is like a super-version of Tomcat, providing data management and persistence, in addition to HTTP request
processing (JBoss uses a portion of Tomcat for this purpose). JBoss includes container management of persistence,
it includes separation of web application and business logic portions; it includes the JMX infrastructure, and it
includes message-driven beans with JMS.
JBoss is such a large set of facilities that it is hard to learn which ones to use under what conditions. Hence, there
are both reference manuals, and usage-oriented tutorials.
The standard that is most specific to J2EE application servers (now called JEE application servers, with the
release of Java 5) is the Enterprise Java Bean (EJB) standard. This has been greatly revised from version 1.0 to 2.0
to 3.0. EJB 3.0 is a major step forward, and is a primary focus of this document.
While not discussed here, the major competing application server products include Suns Glassfish, and BEAs
WebLogic, IBMs WebSphere, and Oracles OC4J. In early 2008, Oracle acquired BEA.
This document begins with the release specification notes for JBoss, and then focuses on EJB 3.0 and related Java
EE 5.0 services for the main text. Then it concludes with a number of JBoss-based examples, derived from the
Workbook part of the Burke and Monson-Haefel book. This document also contains a number of places where
Seam is discussed, particularly how Seam extends the session bean management facilities to provide stateful
components.
Page 1 of 35
The current 4.2.x version as of this writing is 4.2.3.GA released July 18, 2008. The 4.2.x versions are important
because they are the first versions to deploy EJB3 natively. The 4.2.3 version includes a number of fixes and
number of updated dependent libraries such as JSF, JAX-WS, JBoss Cache, and Javassist. Specific patches in 4.2.3
include:
The 4.2.x releases are considered transitional between 4.x and 5.x, because they implement EJB 3.0, but are still
considered a Java EE 1.4 product rather than Java EE 5. With mostly new support for JEE tools and technologies
that are key to Java EE 5. The major new improvements in 4.2.x include:
Full support of JAX-WS, by including version 2.0.x of JAX-WS as the web services implementation
Full support of Java 1.6
Tomcat 6.0, which adds support for JSP 2.1 and Servlet 2.5
JavaServer Faces 1.2 integration (this is based on Suns implementation)
JBoss Transactions (Arjuna) JTA 4.2.3 as the default transaction monitor
Integration of Hibernate 3.2.3.GA
Integration of Hibernate Annotations 3.3.0.GA
There were a number of 4.0.x versions, which implement a Java EE 1.4 application server, with embedded Apache
Tomcat 5.5. They included JavaServer Faces 1.1 (using Apache MyFaces). Any Java Virtual Machine
implementation between versions 1.4 and 1.5 is supported. The 4.0.x versions of JBoss were released in late 2005
through 2007.
Resources
JBoss in Action: Configuring the JBoss Application Server by Javid Jamae and Peter Johnson. Manning Press,
January 2009, 496 pages. List price $49.99, Amazon price $31.49, used from $23.77. Rated 5 stars on Amazon.com
(from 3 reviews). This is the first book to focus on teaching readers in detail how to use the JBoss application
server. Unlike other titles about JBoss, the authors of JBoss in Action go deeper into the advanced features and
configuration of the server. In particular, it focuses on enterprise-class topics, such as high availability, security, and
performance. This book walks readers through the JBoss 5 Application Server from installation to configuration to
production development. It is not as much of a developers guide as it is an administrators guide and an architects
guide to some of the advanced features, which include JBoss Seam and JBoss Portal.
Enterprise Java Beans 3.0 (Fifth Edition) by Bill Burke and Richard Monson-Haefel. OReilly Press, May 2006,
760 pages. List price $49.99, Amazon price $34.66, used from $20.12. Rated 4.5 stars on Amazon. This fifth
edition, written by Bill Burke and Richard Monson-Haefel, has been updated to capture the very latest need-to-know
Java technologies in the same award-winning fashion that drove the success of the previous four strong-selling
Page 2 of 35
editions. Bill Burke, Chief Architect at JBoss, Inc., represents the company on the EJB 3.0 and Java EE 5
specification committees. Richard Monson-Haefel is one of the world's leading experts on Enterprise Java. The
book is organized into two parts: the technical manuscript followed by the JBoss workbook. The technical
manuscript explains what EJB is, how it works, and when to use it. The JBoss workbook provides step-by-step
instructions for installing, configuring, and running the examples from the manuscript on the JBoss 4.0.x
Application Server. Buy this book.
EJB 3 in Action by Panda, Rahman, and Lane. Manning Press, April 2007, 712 pages. List price $49.99, Amazon
price $39.40, used from $34.50. Rated 4 stars on Amazon.com. Considered to be a very nice and broad developers
guide coverage of EJB 3 with a very simple and excellently crafted case study. The book starts very lightly on this
complex subject and slowly dives into the details of advanced concepts like JPA, interceptors, transactions, security,
and performance issues. If develops each facility within the case study. We liked the idea of case study starting
simple and developing it based on complexity. Some reviews stated that it was a very good book with a very
smooth read, while other reviews stated that it was poorly worded, however. The book also has comparisons of EJB
3 with Spring. This book is available as an e-book in the IEEE Computer Society Safari bookshelf.
Beginning EJB 3 Application Development: From Novice to Professional by Kodali, Weatherby, and Zedroni.
APress, September 2006, 512 pages. List price $44.95, Amazon price $35.66, used from $17.88. Rated 4 stars on
Amazon. Opinions varied greatly, from 1 star to 5 stars. Similar in content to the above books.
JBoss at Work by Tom Marrs and Scott Davis. OReilly Press, 306 pages, October 2005. List price $34.95,
Amazon price $23.07, used from $18.66. Rated 4.5 stars on Amazon.com. Described as a great overview of a broad
spectrum of product technologies. It spends enough time on each to get them working and to provide a feel for their
value, customizability, and flexibility. Examples are well-presented and contain discussion about how they work
and are configured for multiple popular application environments, where appropriate. It has excellent background
and history for each technology, popular alternatives, and a discussion about why the author preferred this particular
technology. In other words, the authors provide more than just the bare mention included in many "survey" books.
There is enough to get all of them working, and working together as a cohesive set. It does not, however, provide a
lot of detail on each one. Unfortunately the book represents a transition between the EJB 2.0 world and the EJB 3.0
world, and hence many examples are described in terms of EJB 2.0. It uses JBoss 4.0.x rather than 4.2.x.
Mastering Enterprise JavaBeans 3.0 by Sriganesh, Brose, and Silverman, Wiley, July 2006, 685 pages. List price
$44.99, Amazon price $29.19, Used from $19.55. Rated 4 stars on Amazon.com. Opinions varied greatly, some
comments indicating that it was a great reference, others thinking that it was little more than the online tutorial. We
have a copy from the Palo Alto library. The most useful chapter is a comparison of EJB 2.0 and 3.0.
JBoss: A Developers Notebook by Norman Richard. O'Reilly Media, Inc., June 2005, 172 pages. Rated 4 stars
on Amazon. List price $29.99, Amazon price $19.33, used from $7.90. This is perhaps the oldest book that is still
relevant, though it still predates EJB 3.0. However, it provides a very friendly and try things out style of writing,
which we have found useful when learning something new and complex for the first time.
JBoss-Provided Documentation
There is basically no documentation in the download itself. There are four examples, but these are not particularly
relevant to our projects and usage of JBoss or EJB 3.0.
Instead you should read the JBoss Getting Started online book at
http://docs.jboss.org/jbossas/getting_started/v4/html/
These are focused on a tutorial called the Dukes Bank application, which has account and transaction records. This
is quite useful, as it builds out entity beans, session beans, and more.
Page 3 of 35
Examples of the other services include state management, transactions, clustering, messaging, timers, etc. Java EE 5
and EJB 3.0 can be thought of as a virtual machine like the JVM itself, but with support for enterprise
applications. This way of thinking about Java EE 5 appeared in the Panda, Rahman, and Lane book and seems quite
on target.
EJB 3.0 is an outgrowth of the earlier EJB 2.x specification, which included most of the above, including all of the
persistence facilities, however, EJB 3.0 is far easier to use, as it is built around POJOs plus Java Annotations.
The EJB 3.0 specification was generated from about 2003 to 2005, and has led to a major resurgence of JEE servers
and tools.
The biggest changes in the EJB 3.0 specification are the removal of deployment descriptors and the new
specification for persistence, called the Java Persistence API. This new API is very heavily based on facilities
within Hibernate, and while an App Server may use Hibernate underneath (JBoss does), the API has definitions
within packages such as javax.persistence that provide a wrapper over Hibernate and hence you dont see it directly.
Page 4 of 35
An example would be the TravelAgent and ReservationProcessor session beans, which are responsible for making a
reservation, can even access the database directly, and perform reads, writes, and updates to the data. But theres no
Travel Agent or ReservationProcessor record in the database.
A session bean has a remote interface and a local interface. The former is an interface annotation with @Remote,
and the latter is annotated @Local. These indicate the importance given to Java Annotations within EJB 3.0, while
it is still possible to use XML deployment descriptors to define the same thing.
A typical example would be:
@Remote
public interface CalcuatorRemote {
public int add(int x, int y);
public int subtract(int x, int y);
}
Services
In this section, we briefly introduce some of the services that an EJB container offers. Obviously, we can't explain
the implementation details of each service in this section. Neither is it necessary to cover every service EJB offers
right now. The table below from the Panda, Rahman, and Lane book briefly lists the major EJB 3 services and
explains what they mean to you from a practical perspective.
Service
Applies To
Integration
Session
beans and
MDBs
Pooling
Stateless
session
beans,
MDBs
For each EJB component, the EJB platform creates a pool of component
instances that are shared by clients. At any point in time, each pooled instance
is only allowed to be used by a single client. As soon as an instance is finished
servicing a client, it is returned to the pool for reuse instead of being frivolously
discarded for the garbage collector to reclaim.
Page 5 of 35
Service
Applies To
Thread-safety
Session
beans and
MDBs
EJB makes all components thread-safe and highly performant in ways that are
completely invisible. This means that you can write your server components as
if you were developing a single-threaded desktop application. It doesn't matter
how complex the component itself is; EJB will make sure it is thread-safe.
State management
Stateful
session
beans
The EJB container manages state transparently for stateful components instead
of having you write verbose and error-prone code for state management. This
means that you can maintain state in instance variables as if you were
developing a desktop application. EJB takes care of all the details of session
maintenance behind the scenes.
Messaging
MDBs
Transactions
Session
beans and
MDB
Security
Session
beans
Interceptors
Session
beans and
MDBs
In EJB 3, you can make components remotely accessible without writing any
code. In addition, EJB 3 enables client code to access remote components as if
they were local components using DI.
Web services
Stateless
session
beans
EJB 3 can transparently turn business components into robust web services
with minimal code change.
Persistence
Entities
Caching and
performance
Entities
Deployment
An application consists of class file and their other resources zipped up into EAR file, which is a special kind of
JAR file. Upon opening the JAR file, the EJB container scans all classes for annotations such as @Stateless to find
these special classes there is no directory or manifest maintenance that is needed.
Page 6 of 35
There are number of important naming conventions that are often used, such as having all beans have names that
end in impl, or bean. While this was more important in EJB 2, it is less critical in EJB 3, because there are
fewer classes to define.
Session Beans
This is most critical area of understand the EJB 3.0 model, since we are already familiar with concepts of persistence
from our experience with Hibernate.
Page 7 of 35
A new instance of a stateful session bean is made each time that it is looked up. The instance is released after some
configurable timeout period.
The lifecycle of a stateful session bean is more complex, as it can be passivated by the server to save resources.
This means that it will be serialized, and stored somewhere. It can be reactivated if there is new traffic (requests)
from the original client. The stateful session bean goes through all of the same container-based method processing
(such as @PostConstruct) that applies to stateless session beans.
Multiple methods can be decorated with the @Remove method. This means that the session bean state can be
removed after that method completes.
Extended persistence contexts are an advanced concept that we dont use as yet. They have the benefit of leaving all
of the objects that are being used remaining the active or managed state.
With Seam, we dont deal with Stateful vs. Stateless session beans, because all session-objects are stateful
components, and you just select their lifetime. For instance the lifetimes can be anything from event (basically no
long-term state, hence stateless) to conversation or session (different variations on stateful session beans).
Example
Here is an example of a session bean from the EJB3 book:
@Stateful
public class TravelAgentImpl implements TravelAgent {
@PersistenceContext
private EntityManager entityManager;
@EJB
private ProcessPaymentLocal process;
private Customer customer;
private Cruise
cruise;
private Cabin
cabin;
public void setCustomer(Customer cust) {
entityManager.create(cust);
this.customer = cust;
}
public void setCabinId(int id) {
this.cabin = entityManager.find(Cabin.class, id);
}
public void setCruiseId(int id) {
this.cruise = entityManager.find(Cruise.class, id);
}
public Reservation bookPassage(String card, double price)
throws IncompleteConversationalState {
if (customer == null || cruise == null || cabin ==null) {
throw new IncompleteConversationalState();
}
try {
Reservation reservation =
new Reservation(customer, cruise, cabin, price, new Date());
entityManager.persist(reservation);
process.byCredit(customer, card, price);
return reservation;
}
Page 8 of 35
Some of the important aspects of this example are the injection of the persistenceContext, and the reference to the
other EJB session bean. Also note how there is state in the session bean, such as the this.customer variable. For
this reason, the Session bean must be declared @Stateful. A stateless session bean has methods for which all input
is located in the parameters.
The lifecycle of stateful session is only as long as the conversation. A conversation is started when the stateful
session bean is looked up, and completed when the conversation times out.
The business methods and lifecycle callback methods may be defined either in the bean class or in a
superclass. It's worth mentioning here that annotation inheritance is supported with several limitations with
EJB 3 session beans. For example, the bean type annotation @Stateless or @Stateful specified in
the PlaceBidBean superclass will be ignored when you deploy the BidManagerBean. However, any
annotations in the superclasses used to define lifecycle callback methods (more about that later in this
section) and resource injections will be inherited by the bean class.
Business method names must not start with "ejb." For example, avoid a method name like ejbCreate or
ejbAddBid because it may interfere with EJB infrastructure processing. You must define all business
methods as public, but not final or static. If you are exposing a method in a remote business interface of the
EJB, then make sure that the arguments and the return type of the method implement the
java.io.Serializable interface.
javax.annotation.
PostConstruct
Stateless,
stateful,
MDB
javax.annotation.
PreDestroy
Stateless,
stateful,
MDB
Page 9 of 35
Callback Annotation
javax.ejb.PrePassivate
Stateful
javax.ejb.PostActivate
Stateful
These are the only few stateful beanspecific features that we needed to talk about! Before concluding this section
on stateful beans, we'll briefly summarize the differences between stateful and stateless session beans as a handy
reference:
Features
Stateless
Stateful
Conversational state
No
Yes
Pooling
Yes
No
Performance problems
Unlikely
Possible
Lifecycle events
PostConstruct,
PreDestroy
PostConstruct, PreDestroy,
PrePassivate, PostActivate
Timer
Yes
No
SessionSynchronization for
transactions
No
Yes
Web services
Yes
No
Extended PersistenceContext
No
Yes
Page 10 of 35
void joinTransaction( );
void flush( );
FlushModeType getFlushMode( );
void setFlushMode(FlushModeType type);
public
public
public
public
public
Query
Query
Query
Query
Query
createQuery(String queryString);
createNamedQuery(String name);
createNativeQuery(String sqlString);
createNativeQuery(String sqlString, String resultSetMapping);
createNativeQuery(String sqlString, Class resultClass);
The most commonly used methods are persist(), find(), merge(), remove(), lock(), and createQuery();
You obtain an entity manager by using the @PersistenceContext annotation, such as
@PersistenceContext
private EntityManager entityManager;
This will get the default EntityManager, whose definition is created through the persistence.xml file and its related
data source definition files.
There are other ways of getting an entityManager, which allow for special attributes to be defined, or to have
multiple entityManagers each for a different data source.
name
You are required to name your persistence unit. If your persistence classes are within a EJB JAR archive,
and it is the only persistence unit defined, then you do not have to reference this name explicitly in your
@PersistenceContext and @PersistenceUnit annotations.
jta-data-source, non-jta-data-source
Page 11 of 35
This is the JNDI name of where the javax.sql.DataSource is located. This is ignored when *not* used
within an application server. When running outside of an application server, you must specify JDBC
connections with Hibernate specific properties (see below). If you're running inside JBoss, put the jndi
name of the datasource you defined in the earlier section. Remember to put the "java:/" in front of the jndi
name you selected for your datasource.
jar-file and class
The class element specifies a fully qualified classname that you will belong to the persistence unit. The jarfile element specifies another jar you want automatically scanned for @Entity classes. When using jar-file,
you must specify a path relative to the jar file the persistence.xml file is in. By default also, the jar the
persistence.xml file is placed in is scanned for @Entity classes as well. Hence you dontoften have to
specify the <jar-file> or <class> elements.
properties
The properties element is used to specify vendor specific properties. This is where you will define your
JBoss and Hibernate specific configurations. You may need to provide information to Hibernate so that it
knows the database vendor dialect (MySQL, Oracle, etc...), caching, as well as other settings.
which would find a SalesOrder with primary key 1 (the assumption here is that the class has a single-part primary
key). The entityManager maps database tables to objects. If there is no object, then the find() method return null.
There is a similar method, called getReference(), which will return an exception of the record is not found.
In EJB 3, there is also a query language, which is based on Hibernates HQL. This is covered in more detail below.
The query language saves you from having to write finder methods for each of the different types of queries, as done
in EJB 3.
To write out a changed object, use the persist(Object object) method.
While most of our applications use persistence session that are maintained as long as we need them (because they
are part of Seam conversations), the EJB literature goes through a bit of detail to discuss the idea of objects that are
part of persistence sessions (in which changes to them are not actually written out until the end of the session), or the
idea of detached objects. The latter are ones that were found as part of a persistence session, but are still used after
the session is closed. Such objects can be serialized out to client, then brought back and merged in. The CAE
Online application worked this way.
Another important note is that one can force changes to be synchronized with the database by calling flush(). By
default flushing automatically happens before a correlated query is executed (inefficient implementations may flush
before any query is executed) and at transaction commit time. You can control this flush behavior with the
FlushModeType value, which is set on the entityManager. See Monson-Haefel pages 81-82.
Finally, it is possible to get a reference to the underlying persistence provider by calling
entityManager.getDelegate(). In JBoss, this will be Hiberate.
Below, we will discuss more advanced aspects of entities, and use of transactions.
Page 12 of 35
The most important annotations are @Table, @Column, @ManyToOne, @JoinColumn, etc.
Since the Java Persistence using Hibernate book (from Manning) covers the same concepts in a little more detail,
see our document Notes on Hibernate for more information. The Burke and Monson-Haefel EJB 3.0 book takes
almost 3 chapters to cover this material.
Basic Annotations
The annotations covered are @Entity, @Table, @Column, @Id, and more.
This chapter in the Burke and Monson-Haefel book also covers the @TableGenerator annotation and the
@SequenceGenerator.
Property mappings include @Transient, @Basic, and @FetchType. There are also @Embedded objects, and
@Temporal. The latter is important to indicate that the mapping of a property whose type is java.util.Date or
java.util.Calendar is to be a Date, a Time, or a Timestamp. By default, timestamp is assumed.
Entity Relationships
Within Java Persistence, you define relationships between objects using the @ManyToOne annotation, and other
annotations. Most of the EJB literate goes through this in great detail, because the community of EJB 2.0
developers has not seen Hibernate before.
Hence, the material is very similar to the chapter in the Hibernate book on advanced mappings and relationships.
It also defines behavior such as Cascade, Persist, and Merge. Again, these parallel the Hibernate material.
Entity Inheritance
This material is also parallel to the Hibernate book, covering approaches to defining inheritance relationships in the
O-R mapping. Since the Hibernate book covers it just as well, we have not paid a great deal of attention to this
chapter itself.
Query Syntax
The basic syntax is select <identifier> from <tableName> <identifier>.
You can also have select <identifier> from <tableName> <identifier> where <condition>
Page 13 of 35
The condition can have parameters such as select c from Customer c where c.firstName=:first and
c.lastName=:last. In this case you would specify the parameters values on the query object.
Two syntaxes are provided: named parameters and positional parameters. Named parameters are recommended.
Typically, we are fetching a set of objects, such as Customer in the above object. In this case the result will be a
List<Customer> object. The Java class for Customer is found by searching from the package containing the query
call, then searching upwards. Typically, the class names are either the name of the class that defines the entity or are
package-absolute.
These examples return objects. However, we can return information which is more basic, as in the example:
select c.firstName, c.lastName from Customer as c
In this case, the result will be a list of the Object arrays, and the values will be stored into each Object array
positionally (i.e., firstName is at [0], and lastName is at [1]). This also avoids the column numbers in JDBC being
numbered from 1 issue.
The constructor to be used for the object can be specified. Lets say that we want to return a firstName/lastName
pair as an instance of the Name class, which has fields called first and last, and an appropriate constructor. You
could then write:
select new com.incra.Name(c.firstName, c.lastName) from Customer c
You can also query for specific fields on the record, and for related records. For example:
select so.creditCard.creditCardCompany.address.state from SalesOrder so.
This query can also be expressed as an inner join (which is more familiar to SQL programmers):
select r from Customer c inner join c.reservations r
The left join syntax enables retrieval of a set of entities where matching values in the join statement may not exist.
For such values, a null value is placed in the result. Here is an example:
select c.firstName, c.lastName, p.number from Customer c left c.phonenumbers p
This can also be expressed as left outer join (syntactic sugar to parallel SQL 92).
The important point here is that the joins are expressed in terms of the fields in the object (such as c.phonenumbers)
rather than writing out the id matches that are typical of joins. Further, the metadata in the class object indicates
what class the joined tables are to be found through (notice that the class of p is never specified here only the
origin class of Customer must be specified).
The fetch join syntax allows you to preload a returned entitys relationships even if the relationship property has a
FetchType of Lazy. For example, lets say we have a defined our customers one-to-many relationship to Phone as
follows:
Page 14 of 35
@OneToMany(fetch=FetchType.LAZY)
public Collection<Phone> getPhones() { return phones; }
The default for fetchType is EAGER, except for a ManyToMany and a OneToMany relationship, for which the
default is LAZY. A fetchType of EAGER means that a persistence provider will load the attribute of an entity
along with the entity, whereas a fetchType of LAZY is a hint to the provider that the attribute need not be fetched
along with the entity.
If we were to loop over a list of customers, and call getPhones() on each one, there would be an additional query
created for each one. This is called an N+1 queries problem. Instead, use
select c from Customer c LEFT JOIN FETCH c.phones
The key in this example is the word JOIN, which causes a join to be made in the resulting query. Now the phones
will be loaded in join when the customers are loaded.
Note that in Hibernate, you can specify a runtime how the fetches are to be carried out by calling
setFetchMode(attributeName, fetchMode). However, there is no similar function in the regular EJB3 persistence
manager, so you must deal with this in the structure of the query strings.
A query can have a where clause which is basically the same as in regular SQL (we are skipping over the
discussion about arithmetic operations in where clauses that appears on pages 185 to 187 of the Burke and MonsonHaefel book).
There are also facilities for comparing with NULL and NOT NULL.
The discussion regarding order by and group by is basically the same as in SQL and Hibernate. You must be
careful which basic fields you use in the ORDER BY clause. If the query selects a collection of entities, then the
ORDER BY clause can be used with only basic fields of the entity type that is selected.
Finally, the EJB 3 query language supports the operators such as max/min/sum/avg on the specific fetched basic
fields of the entities.
Also finally, the EJB query language supports subqueries (or subselects). I dont know what happens if the
underlying database doesnt support such, perhaps it breaks the queries up into distinct ones.
Query API
package javax.persistence;
public interface Query {
public List getResultList( );
public Object getSingleResult( );
public int executeUpdate( );
public Query setMaxResults(int maxResult);
public Query setFirstResult(int startPosition);
public Query setHint(String hintName, Object value);
public Query setParameter(String name, Object value);
public Query setParameter(String name, Date value, TemporalType temporalType);
public Query setParameter(String name, Calendar value, TemporalType temporalType);
public Query setParameter(int position, Object value);
public Query setParameter(int position, Date value, TemporalType temporalType);
public Query setParameter(int position, Calendar value, TemporalType temporalType);
public Query setFlushMode(FlushModeType flushMode);
}
Page 15 of 35
The three most common calls are: getResultList(), getSingleResult(), and executeUpdate(). The getSingleResult()
will throw a NonUniqueResultException if more than one record meets the query condition.
Queries are made using the following API on the EntityManager:
package javax.persistence;
public interface
public Query
public Query
public Query
public Query
public Query
}
EntityManager {
createQuery(String ejbqlString);
createNamedQuery(String name);
createNativeQuery(String sqlString);
createNativeQuery(String sqlString, Class resultClass);
createNativeQuery(String sqlString, String resultSetMapping);
Query Examples
public List findByName(String first, String last) {
Query query = entityManager.createQuery(
"from Customer c where c.firstName=:first and
c.lastName=:last");
query.setParameter("first", first);
query.setParameter("last", last);
return query.getResultList( );
}
Paging Results
Sometimes an executed query returns too many results. For instance, maybe we're displaying a list of customers on
a web page. The web page can display only so many customers, and maybe there are thousands or even millions of
customers in the database. The Query API has two built-in functions to solve this type of scenario:
setMaxResults( ) and setFirstResult( ):
public List getCustomers(int max, int index) {
Query query = entityManager.createQuery("from Customer c");
return query.setMaxResults(max).
setFirstResult(index).
getResultList( );
}
The getCustomers( ) method executes a query that obtains all customers from the database. We limit the
number of customers it returns by using the setMaxResults( ) method, passing in the max method parameter.
The method is also designed so that you can define an arbitrary set of results that you want returned by the execution
of the query. The setFirstResult( ) method tells the query what position in the executed query's result set
you want returned. So, if you had a max result of 3 and a first result of 5, customers 5, 6, and 7 would be returned.
We set this value in the getCustomers( ) method with the index parameter. Let's take this method and write
a code fragment that lists all customers in the database:
List results;
int first = 0;
int max = 10;
do {
results = getCustomers(max, first);
Iterator it = results.iterator( );
while (it.hasNext( )) {
Customer c = (Customer)it.next( );
System.out.println(c.getFirstName() + " " + c.getLastName( ));
}
entityManager.clear( );
Page 16 of 35
In this example, we loop through all customers in the database and output their first and last names to the system
output stream. If we had thousands or even millions of customers in the database, we could quickly run out of
memory, as each execution of the getCustomers( ) method would return customers that were still managed by
the entity manager. So, after we are finished outputting a block of customers, we call
EntityManager.clear() to detach these customers and let them be garbage-collected by the Java VM. Use
this pattern when you need to deal with a lot of entity objects within the same transaction.
In this statement, the createNativeQuerymethod takes two parameters: the SQL query and the entity class
being returned. This will become an issue if the query returns more than one entity classwhich is why JPA allows
a @SqlResultSetMappingto be used with the createNativeQuerymethod instead of passing an entity
class. A @SqlResultSetMappingmay be mapped to one or more entities.
Here is an other example: Queries may return multiple objects and/or properties as an array of type Object[],
select mother, offspr, mate.name
from DomesticCat as mother
inner join mother.mate as mate
left outer join mother.kittens as offspr
Page 17 of 35
You may also express queries in the native SQL dialect of your database. This is useful if you want to utilize
database specific features such as query hints or the CONNECT BY option in Oracle. It also provides a clean
migration path from a direct SQL/JDBC based application to Hibernate. Note that Hibernate3 allows you to specify
handwritten SQL (including stored procedures) for all create, update, delete, and load operations (please refer to the
reference guide for more information.)
Lifecycle of Beans
Beans, particularly session beans, have a lifecycle of being created, used destroyed, pooled, archived, recovered, etc.
A series of callbacks let you know what is happening.
As described above, the lifecycle of a session bean is very simple, as it has only two states: Does Not Exist and
Method-Ready Pool. The former is a default state when no such instance exists. The latter is when the instance has
been constructed (i.e., after class.newInstance(), injection processing, and running the @PostConstruct method if
present.
Message-Driven Beans
Message-driven beans are built on JMS, which is similar to TIB/RV. Most of the documentation provides a good bit
of background information on JMS and messages, including suggestions on when to use point-to-point and when to
use publish-and-subscribe.
Page 18 of 35
Interceptors
Interceptors are objects that interpose themselves on method calls or the lifecycle events of session and messagedriven beans. They allow you to encapsulate the common behavior that cuts across large parts of your application.
An example would be to add logging calls to each of your EJB classes.
EJB 3 interceptors implement Aspect Oriented Programming and solve this problem. In our example you simply
create a logging interceptor that does the logging, and you can make it the default interceptor for your application.
The logging interceptor will be executed when any bean method is executed. If the requirement for logging or
profiling changes, then you have to change only one class.
You can also apply the @Interceptors annotation to an entire class. When you do, the interceptor is triggered if
any of the target class's methods are invoked. For example, if the ProfilingInterceptor is applied at the class level as
in the following code, your logMethodEntry method will be invoked when the SalesOrderManager class's
addLineItem or addShipmentAddress method is called by the client:
Page 19 of 35
@Interceptors(ProfilingInterceptor.class)
@Stateless
public class SalesOrderManager implements OrderManager {
public void addLineItem (...
public void addShipmentAddress (...
}
The attachment can also be done through a deployment descriptor file in XML
<assembly-descriptor>
<interceptor-binding>
<ejb-name>SalesOrderManager</ejb-name>
<interceptor-class>
incra.util.ProfilingInterceptor
</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
This would apply to the SalesOrderManager, but you could also indicate a * for all classes.
Other Uses
Not only can you interface method invocations, but you can also intercept EJB lifecycle events.
Transactions
First we define the features of ACID transactions.
Next, we focus on declarative transaction management. Using the TransactionAttribute type attribute, we can
declare a methods transaction rule as one of the following:
MANDATORY
REQUIRED
REQUIRED_NEW
SUPPORTS
NOT_SUPPORTED
NEVER
This information can be given in the annotation or in the XML file, and the annotation approach is suggested.
Pages 366 through 369 of the Burke and Monson-Haefel EJB 3.0 book defines each of the types listed above.
The propagation of transactions is a critical concept. The container implements chains of transactions.
Page 20 of 35
management facilities. It is interesting that the Hibernate book has you performing transaction management, but this
indicates that the container is a stronger tool than the ORMapper.
Finally, the book talks about Exceptions and Transactions, and then conversational persistence contexts. These seem
like good ideas to try out as well.
Page 21 of 35
In the Seam framework, there are additional facilities for handling security, including an authenticate method which
can be defined, and an authentication component that is typically created via the component configuration facilities.
Web Services
Java EE 5 provides a robust platform on which you can build and deploy web services. Java EE 5 allows you to
build web services with either regular Java class (POJO) or EJB 3 stateless session beans. In this section we'll
briefly introduce the web services platform and then explain why you would choose EJB 3 session beans over
POJOs.
Standards
Specification
Purpose
Page 22 of 35
Examples
package com.titan.webservice;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.jws.WebMethod;
@Stateless
@WebService(name = "TravelAgent")
public class TravelAgentBean
{@WebMethod(operationName = "Reserve")
public String makeReservation(int cruiseId, int cabinId,
int customerId, double price) {
...
}
}
Java Mail
JEE 5 has Java Mail facilities. See our document Notes on Java Mail.
Page 23 of 35
Logging
See our document Notes on Java Logging.
Deployment
To understand EJB packaging, you must consider how it fits into the bigger picture of Java EE packaging and know
what constitutes a complete enterprise Java application. Up to this point we have focused on using EJB components
such as session beans and MDBs to build business logic and JPA entities to implement your persistence code.
However, your application will not be complete without a presentation tier that accesses the business logic you built
with EJBs. Most likely, you've used standard technologies such as JSP or JSF to build the web tier of your
applications. These web applications, together with EJBs, constitute an enterprise application that you can deploy to
an application server.
To deploy and run an application, you have to package the complete application togetherthe web module and
EJBsand deploy to an application server. Usually you will group similar pieces of the application together in
modules. Java EE defines a standard way of packaging these modules in JAR files, and specifies the formats for
these JARs. One of the advantages of having these formats defined as part of the specification is that they are
portable across application servers.
Page 24 of 35
The table below lists the archives or modules supported by Java EE 5 and their contents. Note that each archive type
is used for packaging a specific type of module, such as EJB or web. For instance, a WAR is used to package a webtier application module, and the EAR file is intended to be the ber archive containing all the other archives so that
in the end, you're only deploying one file. The application server will scan the contents of the EAR and deploy it.
Type
Description
Descriptor
Contents
CAR
Client
application
archives
applicationclient.xml
EAR
Enterprise
application
archive
application.xml
EJBJAR
EJB Java
archive
ejb-jar.xml
RAR
Resource
adapter archives
ra.xml
Resource adapters.
WAR
Web application
archives
web.xml
To create these files, you can use the jar utility that comes with JDK. The final step is to assemble all the JAR files
into one EAR file for deployment. In 11.3.1 we show you a build script that creates a JAR file. Each of these JAR
types contains an optional deployment descriptor that describes the archive. As we have been discussing throughout
this book, you can use metadata annotations instead of a deployment descriptor.
In this section, we focus primarily on the EAR file and the EJB-JAR file, which contains the session and messagedriven beans, as well as entities. Your EAR file must have an application.xml file at the top level, which provides a
map of the contained pieces:
Page 25 of 35
The .ear file is created by running the jar utility provided in Java multiple times for the different layers, or (more
commonly) writing an Ant script that does that same thing. The Ant versions 1.6 and later have tasks for building
.war and .ear files.
Page 517 discusses whether or not to use EJBs. Situations where they are strong include:
Single and multi-system business transactions
Distributed functionality
Page 26 of 35
Alternatives listed include Spring for the runtime framework, and Hibernate or iBatis for the persistence facilities.
The chapter says that JDO will be retired.
JBoss Workbook
Workbook 1: covers deployment configuration, directory structure, etc.
The directory structure of JBoss is:
The examples are organized as source code plus configuration information, and an ant script that handles build and
deployment. The ant script typically has targets like <defaulttask> (which does a compile and deployment),
compile, clean, and clean.db, and run.client.
Hypersonic is used as the database for JBoss by default.
Page 27 of 35
Regular fields
@Id
@EmbbededId to map a primary key class to the database
Multi-table mapping
Embeddable classes
There is little that is new here for those of us who have used Hibernate outside of JBoss.
Page 28 of 35
The primary one that gave us clarifying insights was inverse. Each relationship has an owning side. You must set
the information into the owning side for it to be persisted. For instance customer::creditCard is owned by customer.
Page 29 of 35
Exercise 11_4: Stateful Session Bean: this is quite interesting example, as it maintains session on the server, but has
the client provide a dispatch loop to ask questions (queries) or make selections. In the example, you can query and
select the cruise, the ship, and the customer, then carry out a reservation. The annotations on the stateful bean are:
@Stateful
public class TravelAgentBean implements TravelAgentRemote {
@PersistenceContext(unitName="titan")
private EntityManager entityManager;
@EJB private ProcessPaymentLocal processPayment;
<methods go here>
}
Exercise 11_5: Annotationless Stateful Session Bean: this is the EJB 2.0 counterpart of the above. The XML file
looks like:
<?xml version="1.0"?>
<ejb-jar
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
version="3.0">
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<remote>com.titan.travelagent.TravelAgentRemote</remote>
<ejb-class>com.titan.travelagent.TravelAgentBean</ejb-class>
<session-type>Stateful</session-type>
<remove-method>
<bean-method>
<method-name>bookPassage</method-name>
</bean-method>
<retain-if-exception>false</retain-if-exception>
</remove-method>
<ejb-local-ref>
<ejb-ref-name>ejb/PaymentProcessor</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.titan.processpayment.ProcessPaymentLocal</local>
<injection-target>
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>processPayment</injection-target-name>
</injection-target>
</ejb-local-ref>
<persistence-context-ref>
<persistence-context-ref-name>
persistence/titan
</persistence-context-ref-name>
<persistence-unit-name>titan</persistence-unit-name>
<injection-target>
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>entityManager</injection-target-name>
</injection-target>
</persistence-context-ref>
</session>
</enterprise-beans>
</ejb-jar>
Which is another way of declaring the stateful session bean called com.titan.travelagent.TravelAgentBean.
Page 30 of 35
The program that receives the completed reservations is called the consumer, and it is to be run in a different
window.
The server bean that is listening simply has a @MessageDrvien annotation attached, as follows:
@MessageDriven(activationConfig={
@ActivationConfigProperty(propertyName="destinationType",
propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",
propertyValue="queue/titan-ReservationQueue")})
public class ReservationProcessorBean implements javax.jms.MessageListener {
@PersistenceContext(unitName= "titan")
private EntityManager em;
@EJB
private ProcessPaymentLocal process;
@Resource(mappedName="java:/JmsXA")
private ConnectionFactory connectionFactory;
public void onMessage(Message message) {
System.out.println("Received Message");
}
}
Page 31 of 35
import javax.ejb.*;
import javax.interceptor.*;
public class Profiler {
@AroundInvoke
public Object profile(InvocationContext invocation) throws Exception {
long startTime = System.currentTimeMillis();
try {
return invocation.proceed();
}
Finally {
long endTime = System.currentTimeMillis() - startTime;
System.out.println("Method " + invocation.getMethod()
+ " took " + endTime + " (ms)");
}
}
}
15.2: Intercepting EJB callbacks: implements the @JndiInjected custom injection annotation discussed in chapter
15. This is not quite as interesting, as it runs during deploy time or load time, rather than runtime.
Page 32 of 35
Running the client code produces the same output as in exercise 4.1, because it is also setting up one cabin row in
the database. However, the client is running a web service invocation to trigger the processing. There are two
primary files that make up the client. The first defines the service, with annotations:
package com.titan.travelagent;
import
import
import
import
javax.jws.WebMethod;
javax.jws.WebParam;
javax.jws.WebResult;
javax.jws.WebService;
import com.titan.domain.Cabin;
@WebService(name="EndpointInterface",
targetNamespace="http://localhost:8080",
serviceName = "TravelAgent")
public interface TravelAgentService {
@WebMethod @WebResult(name="Cabin")
public Cabin findCabin(
@WebParam(name="id")
int id);
@WebMethod
public void createCabin(
@WebParam(name="cabin")
Cabin cabin
);
}
Page 33 of 35
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.doTest(args);
}
}
Page 34 of 35
NoClassDefFoundError one additional reason is that a class can depend upon another class which cannot
be found
Too much visibility there may be duplicate classes
Solving issues:
Know the basics of ClassLoaders and how your particular deployment environment uses them.
Make sure there are no duplicate classes or JAR files
Encapsulate/Minimize Visibility to avoid ClassCastException
Use the correct ClassLoader. Use the ThreadContext ClassLoader.
Open Issues
Assuring scalability (this implies setting up efficient database schema, using multiple servers, managing clusters) is
only partially covered in the material we have read so far.
Assuring fault-tolerance (this implies setting up hot standby severs) is not covered at all in the material read so far.
We think that it is in the JBoss in Action book.
Page 35 of 35