Table 32-1 summarizes the two types of enterprise beans. The following sections discuss each type in more detail.
Table 32-1 Enterprise Bean Types
Enterprise Bean Type
Purpose
Session
Message-driven
Performs a task for a client; optionally, may implement a web service
Acts as a listener for a particular messaging type, such as the Java Message Service API
Stateful session beans are appropriate if any of the following conditions are true.
The bean's state represents the interaction between the bean and a specific client.
The bean needs to hold information about the client across method invocations.
The bean mediates between the client and the other components of the application, presenting a simplified view to the client.
Behind the scenes, the bean manages the work flow of several enterprise beans.
To improve performance, you might choose a stateless session bean if it has any of these traits.
The bean's state has no data for a specific client.
In a single method invocation, the bean performs a generic task for all clients. For example, you might use a stateless session bean to send an email that confirms an online order.
The bean implements a web service.
Singleton session beans are appropriate in the following circumstances.
State needs to be shared across the application.
A single enterprise bean needs to be accessed by multiple threads concurrently.
The application needs an enterprise bean to perform tasks upon application startup and shutdown.
The bean implements a web service.
Message-driven beans have the following characteristics.
They execute upon receipt of a single client message.
They are invoked asynchronously.
They are relatively short-lived.
They do not represent directly shared data in the database, but they can access and update this data.
They can be transaction-aware.
They are stateless.
32.6 Naming Conventions for Enterprise Beans
Because enterprise beans are composed of multiple parts, it's useful to follow a naming convention for your applications. Table 32-2 summarizes the conventions for the example beans in this tutorial.
Table 32-2 Naming Conventions for Enterprise Beans
For more information on Enterprise JavaBeans technology, see
Enterprise JavaBeans 3.2 specification:
Enterprise JavaBeans 3.2 specification project:
Table 34-1 Calendar-Based Timer Attributes
All embeddable enterprise bean containers support the features listed in Table 35-1.
Table 35-1 Required Enterprise Bean Features in the Embeddable Container
Part VIII explores the Java Persistence API. This part contains the following chapters:
Chapter 41, "Creating and Using String-Based Criteria Queries"
Chapter 42, "Controlling Concurrent Access to Entity Data with Locking"
Chapter 44, "Using a Second-Level Cache with Java Persistence API Applications"
37.1.4 Multiplicity in Entity Relationships
Multiplicities are of the following types.
One-to-one: Each entity instance is related to a single instance of another entity. For example, to model a physical warehouse in which each storage bin contains a single widget, StorageBin and Widget would have a one-to-one relationship. One-to-one relationships use the javax.persistence.OneToOneannotation on the corresponding persistent property or field.
One-to-many: An entity instance can be related to multiple instances of the other entities. A sales order, for example, can have multiple line items. In the order application, CustomerOrder would have a one-to-many relationship with LineItem. One-to-many relationships use the javax.persistence.OneToManyannotation on the corresponding persistent property or field.
Many-to-one: Multiple instances of an entity can be related to a single instance of the other entity. This multiplicity is the opposite of a one-to-many relationship. In the example just mentioned, the relationship to CustomerOrder from the perspective of LineItem is many-to-one. Many-to-one relationships use the javax.persistence.ManyToOne annotation on the corresponding persistent property or field.
Many-to-many: The entity instances can be related to multiple instances of each other. For example, each college course has many students, and every student may take several courses. Therefore, in an enrollment application, Course and Student would have a many-to-many relationship. Many-to-many relationships use the javax.persistence.ManyToMany annotation on the corresponding persistent property or field.
37.1.5 Direction in Entity Relationships
The direction of a relationship can be either bidirectional or unidirectional. A bidirectional relationship has both an owning side and an inverse side. A unidirectional relationship has only an owning side. The owning side of a relationship determines how the Persistence runtime makes updates to the relationship in the database.
37.1.5.1 Bidirectional Relationships
In a bidirectional relationship, each entity has a relationship field or property that refers to the other entity. Through the relationship field or property, an entity class's code can access its related object. If an entity has a related field, the entity is said to "know" about its related object. For example, if CustomerOrder knows whatLineItem instances it has and if LineItem knows what CustomerOrder it belongs to, they have a bidirectional relationship.
Bidirectional relationships must follow these rules.
The inverse side of a bidirectional relationship must refer to its owning side by using the mappedBy element of the @OneToOne, @OneToMany, or @ManyToManyannotation. The mappedBy element designates the property or field in the entity that is the owner of the relationship.
The many side of many-to-one bidirectional relationships must not define the mappedBy element. The many side is always the owning side of the relationship.
For one-to-one bidirectional relationships, the owning side corresponds to the side that contains the corresponding foreign key.
For many-to-many bidirectional relationships, either side may be the owning side.
37.1.5.2 Unidirectional Relationships
In a unidirectional relationship, only one entity has a relationship field or property that refers to the other. For example, LineItem would have a relationship field that identifies Product, but Product would not have a relationship field or property for LineItem. In other words, LineItem knows about Product, but Product doesn't know which LineItem instances refer to it.
37.1.5.3 Queries and Relationship Direction
Java Persistence query language and Criteria API queries often navigate across relationships. The direction of a relationship determines whether a query can navigate from one entity to another. For example, a query can navigate from LineItem to Product but cannot navigate in the opposite direction. For CustomerOrderand LineItem, a query could navigate in both directions because these two entities have a bidirectional relationship.
37.6 Further Information about Persistence
For more information about the Java Persistence API, see
Java Persistence 2.1 API specification:
EclipseLink, the Java Persistence API implementation in GlassFish Server:
EclipseLink team blog:
EclipseLink wiki documentation:
An identifier is a sequence of one or more characters. The first character must be a valid first character (letter, $, _) in an identifier of the Java programming language, hereafter in this chapter called simply "Java." Each subsequent character in the sequence must be a valid nonfirst character (letter, digit, $, _) in a Java identifier. (For details, see the Java SE API documentation of the isJavaIdentifierStart and isJavaIdentifierPart methods of the Character class.) The question mark (?) is a reserved character in the query language and cannot be used in an identifier.
A query language identifier is case-sensitive, with two exceptions:
Keywords
Identification variables
An identifier cannot be the same as a query language keyword. Here is a list of query language keywords:
ABS
ALL
AND
ANY
AS
ASC
AVG
BETWEEN
BIT_LENGTH
BOTH
BY
CASE
CHAR_LENGTH
CHARACTER_LENGTH
CLASS
COALESCE
CONCAT
COUNT
CURRENT_DATE
CURRENT_TIMESTAMP
DELETE
DESC
DISTINCT
ELSE
EMPTY
END
ENTRY
ESCAPE
EXISTS
FALSE
FETCH
FROM
GROUP
HAVING
IN
INDEX
INNER
IS
JOIN
KEY
LEADING
LEFT
LENGTH
LIKE
LOCATE
LOWER
MAX
MEMBER
MIN
MOD
NEW
NOT
NULL
NULLIF
OBJECT
OF
OR
ORDER
OUTER
POSITION
SELECT
SET
SIZE
SOME
SQRT
SUBSTRING
SUM
THEN
TRAILING
TRIM
TRUE
TYPE
UNKNOWN
UPDATE
UPPER
VALUE
WHEN
WHERE
The following list defines some of the terms referred to in this chapter.
Abstract schema: The persistent schema abstraction (persistent entities, their state, and their relationships) over which queries operate. The query language translates queries over this persistent schema abstraction into queries that are executed over the database schema to which entities are mapped.
Abstract schema type: The type to which the persistent property of an entity evaluates in the abstract schema. That is, each persistent field or property in an entity has a corresponding state field of the same type in the abstract schema. The abstract schema type of an entity is derived from the entity class and the metadata information provided by Java language annotations.
Backus-Naur Form (BNF): A notation that describes the syntax of high-level languages. The syntax diagrams in this chapter are in BNF notation.
Navigation: The traversal of relationships in a query language expression. The navigation operator is a period.
Path expression: An expression that navigates to an entity's state or relationship field.
State field: A persistent field of an entity.
Relationship field: A persistent field of an entity whose type is the abstract schema type of the related entity.
Here is the entire BNF diagram for the query language:
QL_statement ::= select_statement | update_statement | delete_statement select_statement ::= select_clause from_clause [where_clause] [groupby_clause] [having_clause] [orderby_clause] update_statement ::= update_clause [where_clause] delete_statement ::= delete_clause [where_clause] from_clause ::= FROM identification_variable_declaration {, {identification_variable_declaration | collection_member_declaration}}* identification_variable_declaration ::= range_variable_declaration { join | fetch_join }* range_variable_declaration ::= abstract_schema_name [AS] identification_variable join ::= join_spec join_association_path_expression [AS] identification_variable fetch_join ::= join_specFETCH join_association_path_expression association_path_expression ::= collection_valued_path_expression | single_valued_association_path_expression join_spec::= [LEFT [OUTER] |INNER] JOIN join_association_path_expression ::= join_collection_valued_path_expression | join_single_valued_association_path_expression join_collection_valued_path_expression::= identification_variable.collection_valued_association_field join_single_valued_association_path_expression::= identification_variable.single_valued_association_field collection_member_declaration ::= IN (collection_valued_path_expression) [AS] identification_variable single_valued_path_expression ::= state_field_path_expression | single_valued_association_path_expression state_field_path_expression ::= {identification_variable | single_valued_association_path_expression}.state_field single_valued_association_path_expression ::= identification_variable.{single_valued_association_field.}* single_valued_association_field collection_valued_path_expression ::= identification_variable.{single_valued_association_field.}* collection_valued_association_field state_field ::= {embedded_class_state_field.}*simple_state_field update_clause ::=UPDATE abstract_schema_name [[AS] identification_variable] SET update_item {, update_item}* update_item ::= [identification_variable.]{state_field | single_valued_association_field} = new_value new_value ::= simple_arithmetic_expression | string_primary | datetime_primary | boolean_primary | enum_primary simple_entity_expression | NULL delete_clause ::= DELETE FROM abstract_schema_name [[AS] identification_variable] select_clause ::= SELECT [DISTINCT] select_expression {, select_expression}* select_expression ::= single_valued_path_expression | aggregate_expression | identification_variable | OBJECT(identification_variable) | constructor_expression constructor_expression ::= NEW constructor_name(constructor_item {, constructor_item}*) constructor_item ::= single_valued_path_expression | aggregate_expression aggregate_expression ::= {AVG |MAX |MIN |SUM} ([DISTINCT] state_field_path_expression) | COUNT ([DISTINCT] identification_variable | state_field_path_expression | single_valued_association_path_expression) where_clause ::= WHERE conditional_expression groupby_clause ::= GROUP BY groupby_item {, groupby_item}* groupby_item ::= single_valued_path_expression having_clause ::= HAVING conditional_expression orderby_clause ::= ORDER BY orderby_item {, orderby_item}* orderby_item ::= state_field_path_expression [ASC |DESC] subquery ::= simple_select_clause subquery_from_clause [where_clause] [groupby_clause] [having_clause] subquery_from_clause ::= FROM subselect_identification_variable_declaration {, subselect_identification_variable_declaration}* subselect_identification_variable_declaration ::= identification_variable_declaration | association_path_expression [AS] identification_variable | collection_member_declaration simple_select_clause ::= SELECT [DISTINCT] simple_select_expression simple_select_expression::= single_valued_path_expression | aggregate_expression | identification_variable conditional_expression ::= conditional_term | conditional_expression OR conditional_term conditional_term ::= conditional_factor | conditional_term AND conditional_factor conditional_factor ::= [NOT] conditional_primary conditional_primary ::= simple_cond_expression |( conditional_expression) simple_cond_expression ::= comparison_expression | between_expression | like_expression | in_expression | null_comparison_expression | empty_collection_comparison_expression | collection_member_expression | exists_expression between_expression ::= arithmetic_expression [NOT] BETWEEN arithmetic_expressionAND arithmetic_expression | string_expression [NOT] BETWEEN string_expression AND string_expression | datetime_expression [NOT] BETWEEN datetime_expression AND datetime_expression in_expression ::= state_field_path_expression [NOT] IN (in_item {, in_item}* | subquery) in_item ::= literal | input_parameter like_expression ::= string_expression [NOT] LIKE pattern_value [ESCAPE escape_character] null_comparison_expression ::= {single_valued_path_expression | input_parameter} IS [NOT] NULL empty_collection_comparison_expression ::= collection_valued_path_expression IS [NOT] EMPTY collection_member_expression ::= entity_expression [NOT] MEMBER [OF] collection_valued_path_expression exists_expression::= [NOT] EXISTS (subquery) all_or_any_expression ::= {ALL |ANY |SOME} (subquery) comparison_expression ::= string_expression comparison_operator {string_expression | all_or_any_expression} | boolean_expression {= |<> } {boolean_expression | all_or_any_expression} | enum_expression {= |<> } {enum_expression | all_or_any_expression} | datetime_expression comparison_operator {datetime_expression | all_or_any_expression} | entity_expression {= |<> } {entity_expression | all_or_any_expression} | arithmetic_expression comparison_operator {arithmetic_expression | all_or_any_expression} comparison_operator ::= = |> |>= |< |<= |<> arithmetic_expression ::= simple_arithmetic_expression | (subquery) simple_arithmetic_expression ::= arithmetic_term | simple_arithmetic_expression {+ |- } arithmetic_term arithmetic_term ::= arithmetic_factor | arithmetic_term {* |/ } arithmetic_factor arithmetic_factor ::= [{+ |- }] arithmetic_primary arithmetic_primary ::= state_field_path_expression | numeric_literal | (simple_arithmetic_expression) | input_parameter | functions_returning_numerics | aggregate_expression string_expression ::= string_primary | (subquery) string_primary ::= state_field_path_expression | string_literal | input_parameter | functions_returning_strings | aggregate_expression datetime_expression ::= datetime_primary | (subquery) datetime_primary ::= state_field_path_expression | input_parameter | functions_returning_datetime | aggregate_expression boolean_expression ::= boolean_primary | (subquery) boolean_primary ::= state_field_path_expression | boolean_literal | input_parameter enum_expression ::= enum_primary | (subquery) enum_primary ::= state_field_path_expression | enum_literal | input_parameter entity_expression ::= single_valued_association_path_expression | simple_entity_expression simple_entity_expression ::= identification_variable | input_parameter functions_returning_numerics::= LENGTH(string_primary) | LOCATE(string_primary, string_primary[, simple_arithmetic_expression]) | ABS(simple_arithmetic_expression) | SQRT(simple_arithmetic_expression) | MOD(simple_arithmetic_expression, simple_arithmetic_expression) | SIZE(collection_valued_path_expression) functions_returning_datetime ::= CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP functions_returning_strings ::= CONCAT(string_primary, string_primary) | SUBSTRING(string_primary, simple_arithmetic_expression, simple_arithmetic_expression)| TRIM([[trim_specification] [trim_character] FROM] string_primary) | LOWER(string_primary) | UPPER(string_primary) trim_specification ::= LEADING | TRAILING | BOTH
This chapter describes how to create weakly typed string-based Criteria API queries.
The following topics are addressed here:
Part IX introduces messaging. This part contains the following chapters:
45 Java Message Service Concepts
This chapter provides an introduction to the Java Message Service (JMS) API, a Java API that allows applications to create, send, receive, and read messages using reliable, asynchronous, loosely coupled communication. It covers the following topics:
Figure 45-2 JMS API Architecture
Description of "Figure 45-2 JMS API Architecture"
A point-to-point (PTP) product or application is built on the concept of message queues, senders, and receivers. Each message is addressed to a specific queue, and receiving clients extract messages from the queues established to hold their messages. Queues retain all messages sent to them until the messages are consumed or expire.
PTP messaging, illustrated in Figure 45-3, has the following characteristics.
Each message has only one consumer.
The receiver can fetch the message whether or not it was running when the client sent the message.
Figure 45-3 Point-to-Point Messaging
Description of "Figure 45-3 Point-to-Point Messaging"
Use PTP messaging when every message you send must be processed successfully by one consumer.
In a publish/subscribe (pub/sub) product or application, clients address messages to a topic, which functions somewhat like a bulletin board. Publishers and subscribers can dynamically publish or subscribe to the topic. The system takes care of distributing the messages arriving from a topic's multiple publishers to its multiple subscribers. Topics retain messages only as long as it takes to distribute them to subscribers.
With pub/sub messaging, it is important to distinguish between the consumer that subscribes to a topic (the subscriber) and the subscription that is created. The consumer is a JMS object within an application, while the subscription is an entity within the JMS provider. Normally, a topic can have many consumers, but a subscription has only one subscriber. It is possible, however, to create shared subscriptions; see Creating Shared Subscriptions for details. See Consuming Messages from Topics for details on the semantics of pub/sub messaging.
Pub/sub messaging has the following characteristics.
Each message can have multiple consumers.
A client that subscribes to a topic can consume only messages sent after the client has created a subscription, and the consumer must continue to be active in order for it to consume messages.
The JMS API relaxes this requirement to some extent by allowing applications to create durable subscriptions, which receive messages sent while the consumers are not active. Durable subscriptions provide the flexibility and reliability of queues but still allow clients to send messages to many recipients. For more information about durable subscriptions, see Creating Durable Subscriptions.
Use pub/sub messaging when each message can be processed by any number of consumers (or none). Figure 45-4 illustrates pub/sub messaging.
Figure 45-4 Publish/Subscribe Messaging
Description of "Figure 45-4 Publish/Subscribe Messaging"
Messaging products are inherently asynchronous: There is no fundamental timing dependency between the production and the consumption of a message. However, the JMS specification uses this term in a more precise sense. Messages can be consumed in either of two ways.
Synchronously: A consumer explicitly fetches the message from the destination by calling the receive method. The receive method can block until a message arrives or can time out if a message does not arrive within a specified time limit.
Asynchronously: An application client or a Java SE client can register a message listener with a consumer. A message listener is similar to an event listener. Whenever a message arrives at the destination, the JMS provider delivers the message by calling the listener's onMessage method, which acts on the contents of the message. In a Java EE application, a message-driven bean serves as a message listener (it too has an onMessage method), but a client does not need to register it with a consumer.
45.3 The JMS API Programming Model
The basic building blocks of a JMS application are
Administered objects: connection factories and destinations
Connections
Sessions
JMSContext objects, which combine a connection and a session in one object
Message producers
Message consumers
Messages
Figure 45-5 shows how all these objects fit together in a JMS client application.
Figure 45-5 The JMS API Programming Model
Description of "Figure 45-5 The JMS API Programming Model"
Table 45-1 How JMS Message Header Field Values Are Set
Table 45-2 JMS Message Types
The root class for all checked exceptions in the JMS API is JMSException. The root cause for all unchecked exceptions in the JMS API is JMSRuntimeException.
Catching JMSException and JMSRuntimeException provides a generic way of handling all exceptions related to the JMS API.
The JMSException and JMSRuntimeException classes include the following subclasses, described in the API documentation:
IllegalStateException, IllegalStateRuntimeException
InvalidClientIDException, InvalidClientIDRuntimeException
InvalidDestinationException, InvalidDestinationRuntimeException
InvalidSelectorException, InvalidSelectorRuntimeException
JMSSecurityException, JMSSecurityRuntimeException
MessageEOFException
MessageFormatException, MessageFormatRuntimeException
MessageNotReadableException
MessageNotWriteableException, MessageNotWriteableRuntimeException
ResourceAllocationException, ResourceAllocationRuntimeException
TransactionInProgressException, TransactionInProgressRuntimeException
TransactionRolledBackException, TransactionRolledBackRuntimeException
All the examples in the tutorial catch and handle JMSException or JMSRuntimeException when it is appropriate to do so.
Table 45-3 @ActivationConfigProperty Settings for Message-Driven Beans
For more information about JMS, see
Java Message Service website:
Java Message Service specification, version 2.0, available from:
46 Java Message Service Examples
This chapter provides examples that show how to use the JMS API in various kinds of Java EE applications. It covers the following topics:
A final section covers Using NetBeans IDE to Create JMS Resources.
The examples are in the tut-install/examples/jms/ directory.
The steps to build and run each example are as follows.
Use NetBeans IDE or Maven to compile, package, and in some cases deploy the example.
Use NetBeans IDE, Maven, or the appclient command to run the application client, or use the browser to run the web application examples.
Before you deploy or run the examples, you need to create resources for them. Some examples have a glassfish-resources.xml file that is used to create resources for that example and others. You can use the asadmin command to create the resources.
To use the asadmin and appclient commands, you need to put the GlassFish Server bin directories in your command path, as described in SDK Installation Tips.
The following tables list the examples used in this chapter, describe what they do, and link to the section that describes them fully. The example directory for each example is relative to the tut-install/examples/jms/ directory.
Table 46-1 JMS Examples That Show the Use of Java EE Application Clients
Table 46-2 JMS Examples That Show the Use of Java EE Web and EJB Components
Table 46-3 Message Acknowledgment with Synchronous and Asynchronous Consumers
Figure 46-1 Transactions: JMS Client Example