This tutorial revisits the entities from JPA_Tutorial_1_Getting_Started and introduces a DAO, which gets its entity manager auto-wired.
Setting Up Your Project
title: Ejb_3_Tutorial_2_Setting_Up_Your_Project
—
The instructions for setting up your project mirror those from the first tutorial: EJB3_Tutorial_1_Create_and_Configure.
For the remainder of this tutorial, when you see ****, replace it with **Ejb3Tutorial2**.
title: Ejb3EclipseProjectSetupAndConfiguration
—
Create the Project
Pull down the File menu and select new:project
Select Java Project
Click Next
Enter ****
Under Project Layout select create separate source and output folders
Click Finish
Select ****, right-click and select **new:Source Folder**
Enter conf for the name
Click on Finish
Select ****, right-click and select **new:Source Folder**
Enter test for the name
Click on Finish
Edit your project properties
Now that we have created a user library, we can add that user library to our project:
Select ****, and press alt-enter or right-click and select properties.
Select Java Build Path
Select the Libraries tab
Click on Add Library
Select User Library and click Next
Click on the box next to EJB3_EMBEDDABLE and click Finish
Click Add Library
Select JUnit and click Next
In the pull-down list, select JUnit 4 and click Finish
Click on OK to make the change to your project’s classpath
Setup the configuration files
The JBoss Embeddable container looks for several files in the classpath. To keep all of these in one place, we’ll add another source directory to our project and then import several files into that directory.
Select the conf folder under ****
Pull down the File menu and select Import
Expand General
Select File System and click on Next
Click on Browse and go to the following directory: C:/libs/jboss-EJB-3.0_Embeddable_ALPHA_9/conf
Click on OK
You’ll see conf in the left pane, select it
Verify that the Into folder: lists **/conf** (if not, just enter it or browse to it)
Click Finish
Expand the conf directory and verify that the files are now there
Add Resource Adapter Archive(RAR)
The Java Connector system defines Resource Adapter Archive files (RAR files). We need to add a few RAR files into the class path. We will import two more files into the conf directory:
Select the conf folder
Pull down the File menu and select Import
Expand General
Select File System and click on Next
Click on Browse and go to the following directory: C:/libs/jboss-EJB-3.0_Embeddable_ALPHA_9/lib
Select jcainflow.rar and jms-ra.rar
Click Finish
Create a jndi.properties file
Note, depending on the version of the embeddable container you download, you might already have a file called jndi.properties. If you do, skip to the next section.
Select the conf directory, right-click and select new then select File
Enter the name jndi.properties and click finish
Enter the following 2 lines then save and close the file:
Create a persistence.xml
This example presents a utility class we’ll be using later. The container needs a persistence.xml file to operate. This file must be found under a META-INF directory somewhere in the classpath or the embeddable container will not start. The file’s name is persistence.xml with a lower-case ‘p’. On a Unix system, this will make a difference. On a PC, this won’t make a difference and it is one of those things that might work on your machine but not on the linux build box.
Select your src directory
Right-click, select New:Folder
Enter META-INF
Click OK
Select META-INF
Right-lick, select New:File
Enter persistence.xml
Click Finish
Copy the following example into your new file then save it by pressing ctrl-s
persistence.xml
The Entity Model
title: Ejb_3_Tutorial_2_The_Entity_Model
—
Creating the Entity Model
We need to create our entity model. There are three classes in it:
Address
Company
Person
To create the basic classes:
Select the src folder under ****
Right-click and select New::Class
For the package, enter entity
For the name, enter Address, Company, and Person respectively.
Type or enter the source provided below for each of the three classes.
Changes
The entity model is changed slightly from the first JPA tutorial. There is one change in Company.java. Review that class’ comments to understand that change. The quick summary is that we’ve added eager fetching to a relationship.
Address.java
Company.java
Person.java
The Dao and its Interface
title: Ejb_3_Tutorial_2_The_Dao_and_its_Interface
—
We will create a session bean that wraps access to the company behind a session bean interface. This is another example of the Data Access Object (dao) pattern. This is one of the typical ways we use a session bean.
This dao looks pretty much the same as the session bean from our first EJB example. As with the first example, we’ve placed the interface in one package and the implementation (the session bean) in a second interface.
CompanyDao.java
To create this interface:
Expand Ejb3Tutorial2 and select the src directory
Right-click, select New::Interface
Enter dao for the package and CompanyDao for the name
Click Finish
Type the code into the file and save it
CompanyDaoImpl.java
To create this class:
Expand Ejb3Tutorial2 and select the src directory
Right-click, select New::Class
Enter dao.impl for the package and CompanyDaoImpl for the name
Click Finish
Type the code into the file and save it
Starting JBoss EJB 3 Embeddable Container
title: Ejb_3_Tutorial_2_Starting_the_Container
—
As with our first tutorial, we need to be able to start the container. Here’s the JBossUtil class again. Below is the file again. However, to get this file into your new tutorial:
Expand your first project (Ejb3Tutorial1)
Expand the src directory, select the util package
Copy it (ctrl-c or right-click and select copy)
Expand your second project (Ejb3Tutorial2)
Select the src directory
Paste it (ctrl-v or right-click and select paste)
JBossUtil.java
A unit test or main program can use the following code to initialize the JBoss EJB 3 Container:
Smoke Test Suite
title: Ejb_3_Tutorial_2_Smoke_Test_Suite
—
Here is a quick test suite to verify that things basically work. To create this test:
Expand your project (Ejb3Tutorial2)
Select the test source folder
Right-click and select New:Class
Enter dao.impl for the Package
Enter CompanyDaoImplTest for the Class name
Click Finish
Enter the following class
Once the class is saved and compiles, execute it (Right-click in the file, select Run As::JUnit Test
CompanyDaoImplTest.java
Optional: Data Source Configuration
title: Ejb_3_Tutorial_2_Optional_Data_Source_Configuration
—
The persistence.xml file mentions the possibility of using your own data source rather than the default data source to hit a different database.
When you use the embedded container, it looks for a file called embedded-jboss-beans.xml for its datasources (and several other things). In the one that ships with the ALPHA 9 release, you’ll see the following two entries near the bottom:
To create your own data source, you basically copy both of these and update the values accordingly. Here is one example that uses HSQL with a local server:
To use this, you need to do two things. Update persistence.xml and start a HSQL server.
Update persistence.xml
Replace the following line:
With this one:
To start an HSQL server, you can use the following steps:
Under the place where you extracted HSQL (C:\libs\hsqldb if you used the same directories as the tutorial), create a new directory called “databases”.
Change to that directory
Use the following command to start the HSQL server:
Optional: QuantumDB Setup and Configuration
title: QuantumDB_Configuration
—
QuantumDB Configuration
QuantumDB is an Eclipse plugin that lets you view a database. This is a quick start guide.
Open the GEF zip file and extract just the plugins and features directories directly into you eclipse installation (c:\eclipse)
Open the QuantumDB zip file and extract just the plugins and features directories directly into your eclipse installation (c:\eclipse)
Restart Eclipse
Start your Database
This example assumes hypersonic is running with the following startup script:
In our examples, we created a folder called database under the installation directory of hypersonic, so the full folder name is:
Assuming java is in your classpath, the following command will start hypersonic:
JPA in JSE Settings
persistence.xml
JPA in JEE Settings
This assumes you are using the JBoss Embedded container.
And the additions to embedded-jboss-bean.xml:
Using the Perspective
Now that everything is setup, you’ll need to open the perspective and form a connection to the database.
Click the Open Perspective button and select Other
Select Quantum DB and click OK
Right-click in Database Bookmarks pane and select New Bookmark…
Click on the Add Driver button
Click on Add External Jar…
Find hsqldb.jar (c:\libs\hsqldb\lib\hsqldb.jar) and click Open
Click on Browse…
Select org.hsqldb.jdbcDriver and click ok
Click on Finish
Select the driver you just added (it is probably the first in the list but look in the JDBC Driver Name column for org.hsqldb.jdbcDriver
Click Next
In the Userid field, enter sa
Leave the Password field blank
Leave Prompt for Password unselected
In the JDBC URL filed, enter jdbc:hsqldb:hsql://localhost/xdb
Name your bookmark HypersonicLocalServer and click Finish
Double-click on you new HypersonicLocalServer Bookmark
Expand PUBLIC
Expand Tables
At this point you can experiment with the plugin.
Exercises
title: Ejb_3_Tutorial_2_Exercises
—
Fetching and Lazy Initialization
The Company entity has one attribute where we’ve specified the fetch type. Review the employees attribute in Company.java. Remove the fetch = FetchType.EAGER and execute the tests.
There’s another way to make this “work” by manually reading the contents of the collection. Experiment with that and see if you can get it to work using this technique. What is the impact of ) on a lazy fetch? (Hint: you might have some issues with this combination.)
Review
Which approach do you prefer?
What are the advantages/disadvantages?
Give one example where you’d use each technique.
Suggest a way to rewrite this or the test or both to remove the need to perform eager fetching.
Hint: You can compare the SQL from each approach by adding the following line to the persistence.xml:
Fetch and Lazy Initialization Revisited
Add a unit test where you:
Create a person
Create a company
Hire the person
Retrieve the person (you can add a new DAO or simply add a method to the Company Dao)
Verify that they have one job and that it is for the expected company.
Review
Did this test work? If not, why? If so, what can you say about @OneToMany versus @ManyToOne?
If it did not work, fix it.
Add Tests
Review the driver from the first JPA tutorial. Use that as example source from which you can derive tests.
In addition, add the following tests:
Attempt to Hire Person Already Hired
Write a test that creates a Person and 2 companies. Hire the person at the first company. Attempt to hire the person for the second company.
The results should be one of two things (you choose):
The test expects some kind of exception like “Person Has a Job” to be thrown.
You change the relationship between Person and Company to be bi-direction and many to many so that a Person can work for multiple companies.
Hire Person with Same Name/Address
Create two people and hire them both. Make sure this works.
Question, do you think it should work? If not, then update the equals and hashCode method and make this test be one that only works if the attempt fails.
Test Isolation
Use the installed QuantumDB Perspective to discover if our tests are leaving around objects after they have completed. Assuming they have, write code to have each test clean up after itself.
Comments