The exercises in this section reveal some of the basic aspects of
EJB QL programming and
functionality. You’ll explore
basic finder methods,
ejbSelect
methods, and the use of the
IN
operation in EJB QL queries.
Perform the following steps:
Open a command prompt or shell terminal and change to the
ex08_1
directory created by the extraction
process
Set the JAVA_HOME
and
JBOSS_HOME
environment variables to point to where
your JDK and JBoss 4.0 are installed. Examples:
Windows:C:workbookex08_1> set JAVA_HOME=C:jdk1.4.2 C:workbookex08_1> set JBOSS_HOME=C:jboss-
|
Unix:$ export JAVA_HOME=/usr/local/jdk1.4.2 $ export JBOSS_HOME=/usr/local/jboss-4.0
|
Add ant
to your execution path.
Windows:C:workbookex08_1> set PATH=..antin;%PATH%
|
Unix:$ export PATH=../ant/bin:$PATH
|
Perform the build by typing ant
.
As in the last exercise, you will see titan.jar
rebuilt, copied to the JBoss deploy
directory,
and redeployed by the application server.
This exercise introduces no new features in JBoss-specific files. If you think you need to, review Exercise 6.1 of this workbook to understand the JBoss-specific files in this example.
The database tables for this exercise will automatically be created
in JBoss’s default database, HypersonicSQL, when the
EJB JAR is deployed. To initialize all the tables in this example,
though, you must perform the Ant task
run.initialize
:
C:workbookex08_1>ant run.initialize Buildfile: build.xml prepare: compile: run.initialize: [java] added Bill Burke [java] added Sacha Labourey [java] added Marc Fleury [java] added Jane Swift [java] added Nomar Garciaparra
As in the preceding exercise, all business logic is implemented
within a stateless session bean. If you would like to see the
database initialization code, take a look at
com.titan.test.Test81Bean
’s
initialize( )
method, which creates all the entity
beans for this exercise.
Each example method of Test81Bean
implements the
example code fragments shown in the EJB book. Each
Test81Bean
method is invoked by a small, simple
client application.
The Client_81a
program demonstrates a few simple
finder methods that are exposed through the Customer home interface:
public interface CustomerHomeLocal extends javax.ejb.EJBLocalHome { ... public CustomerLocal findByName(String lastName, String firstName) throws FinderException; public Collection findByGoodCredit( ) throws FinderException; ... }
The Customer EJB’s deployment descriptor defines these finder methods as follows:
<query> <query-method> <method-name>findByName
</method-name> <method-params> <method-param>java.lang.String</method-param> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql> SELECT OBJECT(c) FROM Customer c WHERE c.lastName = ?1 AND c.firstName = ?2 </ejb-ql> </query> <query> <query-method> <method-name>findByGoodCredit
</method-name> <method-params/> </query-method> <ejb-ql> SELECT OBJECT(c) FROM Customer c WHERE c.hasGoodCredit = TRUE </ejb-ql> </query>
The example also demonstrates a few
ejbSelect
methods, defined in the Address
EJB’s deployment descriptor as follows:
<query> <query-method> <method-name>ejbSelectZipCodes
</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql> SELECT a.zip FROM Address AS a WHERE a.state = ?1 </ejb-ql> </query> <query> <query-method> <method-name>ejbSelectAll</method-name> <method-params/> </query-method> <ejb-ql> SELECT OBJECT(a) FROM Address AS a </ejb-ql> </query> <query> <query-method> <method-name>ejbSelectCustomer
</method-name> <method-params> <method-param>com.titan.address.AddressLocal</method-param> </method-params> </query-method> <ejb-ql> SELECT OBJECT(C) FROM Customer AS c WHERE c.homeAddress = ?1 </ejb-ql> </query>
Because ejbSelect
methods are private to the
entity bean class, the Address home interface needs custom home
methods to wrap and invoke the private ejbSelect
methods.
public interface AddressHomeLocal extends javax.ejb.EJBLocalHome { ... public CollectionqueryZipCodes
(String state) throws FinderException; public Collection queryAll( ) throws FinderException; public CustomerLocalqueryCustomer
(AddressLocal addr) throws FinderException; }
These custom home
methods need corresponding
ejbHome
methods defined in the Address bean
class. All they do is delegate to the ejbSelect
methods they wrap.
public abstract class AddressBean implements javax.ejb.EntityBean { ... public abstract Collection ejbSelectZipCodes(String state) throws FinderException; public abstract Collection ejbSelectAll( ) throws FinderException; public abstract CustomerLocal ejbSelectCustomer (AddressLocal addr) throws FinderException; public CollectionejbHomeQueryZipCodes
(String state) throws FinderException { return ejbSelectZipCodes(state); } public CollectionejbHomeQueryAll
( ) throws FinderException { return ejbSelectAll( ); } public CustomerLocalejbHomeQueryCustomer
(AddressLocal addr) throws FinderException { return ejbSelectCustomer(addr); } ... }
Custom home methods are described briefly in Chapter 5 of the EJB book and in more detail in Chapter 11. As you can see, they are extremely useful
in exposing private ejbSelect
methods so that they
can be invoked by test programs or business logic. All the workbook
example programs for Chapter 8 use the custom
home methods for this purpose.
Client_81a
invokes these queries and displays
their output. To run it, invoke the Ant task
run.client_81a
. Remember to set your
JBOSS_HOME
and PATH
environment
variables. The output should look something like this:
C:workbookex08_1>ant run.client_81a Buildfile: build.xml prepare: compile: run.client_81a: [java] FIND METHODS [java] -------------------------------- [java] SELECT OBJECT(c) FROM Customer c [java] WHERE c.lastName = ?1 AND c.firstName = ?2 [java] Find Bill Burke using findByName [java] Found Bill Burke [java] [java] SELECT OBJECT(c) FROM Customer c [java] WHERE c.hasGoodCredit = TRUE [java] Find all with good credit. Sacha has bad credit! [java] Bill has good credit. [java] Marc has good credit. [java] Jane has good credit. [java] Nomar has good credit. [java] [java] SELECT METHODS [java] -------------------------------- [java] SELECT a.zip FROM Address AS a [java] WHERE a.state = ?1 [java] show ejbSelectZipCodes with queryZipCodes [java] 01821 [java] 02115 [java] 02116 [java] [java] SELECT OBJECT(a) FROM Address AS a [java] show ejbSelectAll with queryAll [java] 123 Boston Road [java] Billerica, MA 01821 [java] [java] Etwa Schweitzer Strasse [java] Neuchatel, Switzerland 07711 [java] [java] Somewhere Dr. [java] Atlanta, GA 06660 [java] [java] 1 Beacon Street [java] Boston, MA 02115 [java] [java] 1 Yawkey Way [java] Boston, MA 02116 [java] [java] West Broad Street [java] Richmond, VA 23233 [java] [java] Somewhere [java] Atlanta, GA 06660 [java] [java] [java] SELECT OBJECT(C) FROM Customer AS c [java] WHERE c.homeAddress = ?1 [java] show ejbSelectCustomer using Bill's address. [java] The customer is: [java] Bill Burke [java] 123 Boston Road [java] Billerica, MA 01821
The Client_81b
program gives you a chance to
investigate some of the queries illustrated in the EJB book. For an
explanation of the details of the tested queries below, please refer
to Section 8.3.2
in Chapter 8 of the EJB section of this book.
The business logic for this example is implemented in
com.titan.test.Test81Bean
, in the
test81b( )
method.
All the EJB QL queries in this example are
ejbSelect
methods. Again, these
ejbSelect
methods are wrapped by custom home
methods. This example tests the following Customer EJB QL queries and
home methods:
query: |
|
|
|
custom home method: |
|
|
|
query: |
|
|
|
custom home method: |
|
|
|
query: |
|
|
|
custom home method: |
|
|
|
query: |
|
| |
|
|
custom home method: |
|
|
|
query: |
|
| |
|
|
custom home method: |
|
|
|
Client_81b
invokes these queries and displays
their output. To run it, invoke the Ant task
run.client_81b
. Remember to set your
JBOSS_HOME
and PATH
environment
variables. The output should look something like this:
C:workbookex08_1>ant run.client_81b Buildfile: build.xml prepare: compile: run.client_81b: [java] SIMPLE QUERIES with PATHS [java] -------------------------------- [java] SELECT c.lastName FROM Customer AS c [java] Burke [java] Labourey [java] Fleury [java] Swift [java] Garciaparra [java] [java] SELECT c.creditCard FROM Customer c [java] 5324 9393 1010 2929 [java] 5311 5000 1011 2333 [java] 5310 5131 7711 2663 [java] 5810 5881 7788 2688 [java] 5450 5441 7448 2644 [java] [java] SELECT c.homeAddress.city FROM Customer c [java] Billerica [java] Neuchatel [java] Atlanta [java] Boston [java] Boston [java] [java] SELECT c.creditCard.creditCompany.address [java] FROM Customer AS c [java] West Broad Street [java] Richmond, VA 23233 [java] [java] West Broad Street [java] Richmond, VA 23233 [java] [java] West Broad Street [java] Richmond, VA 23233 [java] [java] Somewhere [java] Atlanta, GA 06660 [java] [java] Somewhere [java] Atlanta, GA 06660 [java] [java] [java] SELECT c.creditCard.creditCompany.address.city [java] FROM Customer AS c [java] Richmond [java] Richmond [java] Richmond [java] Atlanta [java] Atlanta
The Client_81c
program lets you investigate some more
queries illustrated in the EJB book. For an explanation of the
details of the tested queries below, please refer to Section 8.3.3
in Chapter 8 of the EJB section. The business
logic for this example is implemented in
com.titan.test.Test81Bean
, in the
test81c( )
method.
All the EJB QL queries in this example are
ejbSelect
methods. Again, these
ejbSelect
methods are wrapped by custom home
methods. This example tests the following Customer EJB QL queries and
home methods:
query: |
|
| |
|
|
custom home method: |
|
|
|
query: |
|
| |
|
|
custom home method: |
|
|
|
query: |
|
| |
| |
|
|
custom home method: |
|
|
|
Client_81c
invokes these queries and displays
their output. To run it, invoke the Ant task
run.client_81c
. Remember to set your
JBOSS_HOME
and PATH
environment
variables. The output should look something like this:
C:workbookex08_1>ant run.client_81c Buildfile: build.xml prepare: compile: run.client_81c: [java] THE IN OPERATOR [java] -------------------------------- [java] SELECT OBJECT( r ) [java] FROM Customer AS c, IN( c.reservations ) AS r [java] Reservation for Alaskan Cruise [java] Reservation for Alaskan Cruise [java] Reservation for Atlantic Cruise [java] Reservation for Atlantic Cruise [java] Reservation for Alaskan Cruise [java] [java] SELECT r.cruise [java] FROM Customer AS c, IN( c.reservations ) AS r [java] Cruise Alaskan Cruise [java] Cruise Alaskan Cruise [java] Cruise Atlantic Cruise [java] Cruise Atlantic Cruise [java] Cruise Alaskan Cruise [java] [java] SELECT cbn.ship [java] FROM Customer AS c, IN( c.reservations ) AS r, [java] IN( r.cabins ) AS cbn [java] Ship Queen Mary [java] Ship Queen Mary [java] Ship Queen Mary [java] Ship Queen Mary [java] Ship Titanic [java] Ship Titanic [java] Ship Titanic [java] Ship Titanic [java] Ship Titanic [java] Ship Titanic [java] Ship Queen Mary [java] Ship Queen Mary