Enterprise Java Beans 3.0
Although named after the ill-fated Enterprise Java Beans standards up to 2.1, the latest version specifies many state-of-the-art technologies and leverages lessons learned from technologies like dependency injection, Hibernate's and TopLink's Entity and Session Management. EJB 3 implements Configuration by Exception, where default values apply as long as these are deduceable from provide information. This results in an easier to develop habit which very often uses a single file per bean including every definition needed.
EJB 3 Entities
To mark the change to earlier versions, EJB 3 removed the Bean from the term Entity Bean and uses Entity. Entities are not bound to the container anymore and can move between the different layers (Model to View to Model and so on) without a specific impact. As a result some design patterns of the EJB 2.x world are not fully applicable (eg. Data Transfer Objects) while others are a possible candidates for an update (eg. Data Access Object). EJB 3 Entities implement the Java Persistence API.
Java Persistence API
The authors of the Java Persistence API (JPA) have learned a lot from ORM frameworks like TopLink or Hibernate and other techniques. The JPA is much more complete then the previous EJB definitions in terms of attribute mapping, inheritance and the query language (JPA Query Language (JQL)).
Implementing the EJB 3 Model Layer
A very easy way to implement the EJB 3 Model Layer is by using the existing Database Model as developed in the previous posts (see
Setting up the Gear,
Creating the Database, and
Deploying the Database Model). Additionally you should make sure that your database is up and running and a
Database Connection called
survey configured. The steps in JDeveloper 10.1.3 and 11g are quite similar.
- Create a Model Layer Project
- Import the EJB 3 from Database Tables
- Check the generated files
- Create a Session Facade
- Create a Test Client
Steps for JDeveloper 10.1.3
Step 1: Create a Model Layer Project
To create a new Model Layer Project select
OnlineSurvey in the
Application Navigator, open the
Context Menu and chose the
New Project... menu entry. In the
New Gallery select an
Empty Project and click on
OK. In the
Create Project window set the
Project Name to
ModelEJB30 and click on the
OK button. Select the newly created
ModelEJB30 project in the
Application Navigator and open the
Project Properties window with a
double-click. In the
Project Properties window, check the values of
Project Content and make sure that the
Default Package is set to
demo.survey.model.ejb30. Click
OK to close this window.
Step 2: Import the EJB 3 from Datbase Tables
Select the
ModelEJB30 project in the
Application Navigator. Open the
New Gallery from the
Context Menu -> New .... In the
New Gallery expand the
Business Tier and select
EJB. On the right-hand side select
Entities From Tables (JPA/EJB 3.0) and click on the
OK button.
- In the Create Entities From Tables wizard step 1 select the survey connection. Click on Next to get the database connection.
- In step 2 click on the Query button to get all available tables. Since we only have tables the check box for Tables is sufficient. Once the table names appear, select all of them.
- Move all entries from Available to Selected, by clicking on the >> button. Note that all names have changed to typical Java type names but in plural (eg. Answers (SURVEY.ANSWERS)). The values in parentheses tell you about the table relationship. Select every entry and see how the text field under the Selected list changes its value. Here we can change the names from plural to singular names. Change the names accordingly. You should have these names: Answer, Author, Item, Question, Response, Survey
- Click Next to go to wizard step 3. In step 3 of the wizard accept the default values and click Next to go to wizard step 4.
- This step can be used for changing the names as well, but is less user-friendly. Click Next to go to the Summary and click on Finish to close the wizard. Now all six entities will be created.
You can find them in the
Application Navigator under
ModelEJB30->Application Sources->demo.survey.model.ejb30.
Step 3: Check the generated files
To check the generated files open them by selecting
Answer.java,
hold the
Shift key, select
Survey.java, open the
Context Menu and select
Go To Bean Class. Every selected file will be opened in a
Code Editor. Select the tab named
Answer.java to bring it to the front. Change the code to get the lines below:
@Entity
@NamedQuery(name = "Answer.findAll", query = "select o from Answer o")
@SequenceGenerator(name = "SEQUENCE_ANSWERS", sequenceName = "SEQ_ANSWERS", allocationSize = 1)
@Table(name = "ANSWERS")
public class Answer implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_ANSWERS")
@Column(nullable = false)
private Long id;
While adding this code, JDeveloper will suggest possible values and actions to be taken. Only import the types
javax.persistence.SequenceGenerator,
javax.persistence.GeneratedValue and
javax.persistence.GenerationType. You should explore how the
Ctrl-Blank short cut helps you to provide the correct annotation parameters.
Do the same for the other files
Author.java,
Item.java,
Question.java,
Response.java,
Survey.java but use
SEQ_AUTHORS with
SEQUENCE_AUTHORS,
SEQ_ITEMS with
SEQUENCE_ITEMS,
SEQ_QUESTIONS with
SEQUENCE_QUESTIONS,
SEQ_RESPONSES with
SEQUENCE_RESPONSES, and
SEQ_SURVEYS with
SEQUENCE_SURVEYS.
Step 4: Create a Session Facade
Click on
ModelEJB30 in the
Application Navigator. Any other entry of the
ModelEJB30 project will do, also. Select
New... from the
Context Menu and navigate to
Business Tier -> EJB in the
New Gallery. On the right-hand side select
Session Bean (EJB 1.1/2.x/3.0) and click on the
OK button to open the 4 step
Create Session Bean wizard.
- In wizard step 1 change the EJB Name to SurveySession, accept the pre-selected defaults and click on Next
- In wizard step 2 make sure that all methods are checked (expand the tree to see which methods are available). Click Next to go to the next wizard step.
- Step 3 shows the default values for the bean class and step 4 - Click Next to go from step 3 to step 4 - shows the implemented interfaces. Remote and Local interfaces are good enough for our scenario.
- Clicking Next in step 4 directs us to the wizard Summary window which we close by clicking on the Finish to go to the next wizard step.
A
SurveySessionBean will be added to the project. Double-click on it and you'll see the generated Session Facade in the
Code Editor.
Step 5: Create a Test Client
To finish the JDeveloper 10.1.3 tasks the creation of a test client needs to be done. Click on the
SurveySessionBean in the
Application Navigator and open the
Context Menu. Find the
New Sample Java Client entry and click on it. Accept all default values and click on the
OK button to generate the test client. Open it and change the main method as follows:
public static void main(String[] args) {
try {
final Context context = getInitialContext();
SurveySession surveySession =
(SurveySession)context.lookup("SurveySession");
Author author = new Author();
author.setName("Olaf Heimburger");
surveySession.persistEntity(author);
for (Author author :
(List<Author>)surveySession.queryAuthorFindAll()) {
System.out.println("id = " + author.getId());
System.out.println("name = " + author.getName());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}To test the Session Facade and the Test Client do the following:
- Select the SurveySessionBean, open the Context Menu and select Run. Wait until you see Oracle Containers for J2EE 10g (10.1.3.3.0) initialized.
- Select the SurveySessionClient, open the Context Menu and select Run. You should get some output.
Steps for JDeveloper 11g
Step 1: Create a Model Layer Project
To create a new Model Layer Project select
OnlineSurvey in the
Application Navigator, click on the
Applications Menu on the right-hand side select the
New
Project... menu entry. In the
New Gallery select an
Empty Project and
click on
OK. In the
Create Project window set the
Project Name to
ModelEJB30 and click on the
OK button. Select the newly created
ModelEJB30 project in the
Application Navigator and open the
Project
Properties window with a double-click. In the
Project Source Paths
window, check the values of
Project Source Paths and make sure that the
Default Package is set to
demo.survey.model.ejb30. Click
OK to close
this window.
Step 2: Import the EJB 3 from Datbase Tables
Select the
ModelEJB30 project in the
Application Navigator. Open the
New Gallery from the
Context Menu -> New .... In the
New Gallery
expand the
Business Tier and select
EJB. On the right-hand side select
Entities From Tables and click on the
OK button.
- In the
Create Entities From Tables wizard step 1 select EJB 3.0 - JPA Entities.
Click on Next to select the Persistence Unit. Since we haven't created one yet, click on the New ... button. In the New Persistence Unit window set the Name to survey and the JTA Datasource Name to jdbc/surveyDS. Click OK to close the window. Click Next to go to the next step.
- In step 3 make sure that the Online Database Connection radio button is checked. Click Next to go to the next step.
- Step 4 lets you define the necessary details for the Database connection and the Offline Database. The Connection should be survey. If this is not available click on the green plus button to create a connection with survey as the Connection Name. For the Offline Database click on the New button and in the Create Offline Database window set the Name and Default Schema to SURVEY. From the Database to emulateOracle10g Express Edition Release 2. Click OK to close this window. Note that this is not really convenient as we did this in the Database project already. So far I didn't found a way to reuse the definitions from the Database project and hope for a dependency-like implementation in the future.
- Click Next to go to step 5. Click on the
Query button to get all available tables. Once the table names appear, select
all of them. Move all entries from Available to Selected, by clicking
on the >> button.
- Click Next to go to wizard step 6. In this step accept the
default values and click Next to go to wizard step 7. In step 7 we have to change the names from plural to singular names. From the drop-down list select one entry after another and remove the last letter s from the Entity Name.
Do this carefully and slowly. In 11g TP 3 chances are that you do it to quick or go to far and you are not able to change anything afterwards. Only solution is start again with the whole wizard. I speak from experience. - Click on Next to go to the Summary step. Click on Finish to create all six entities.
You can find them in the
Application
Navigator under
ModelEJB30->Application
Sources->demo.survey.model.ejb30.
drop-down select
Step 3: Check the generated files
To check the generated files open them by selecting
Answer.java, hold
the
Shift key, select
Survey.java, open the
Context Menu and select
Go
To Bean Class. Every selected file will be opened in the Code Editor.
Select the tab named
Answer.java to bring it to the front. Change the
code to get the lines below:
@Entity
@NamedQuery(name = "Answer.findAll", query = "select o from Answer o")
@SequenceGenerator(name = "SEQUENCE_ANSWERS", sequenceName = "SEQ_ANSWERS", allocationSize = 1)
@Table(name = "ANSWERS")
public class Answer implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_ANSWERS")
@Column(nullable = false)
private Long id;
While adding this code, JDeveloper will suggest possible values and actions to be taken. Only import the types
javax.persistence.GenerationType.
A big improvement is that the EJB 3 Annotations are already known by JDeveloper and do not require any additional action. You should explore how the
Ctrl-Blank short cut helps you to provide the correct annotation parameters.
Do the same for the other files
Author.java,
Item.java,
Question.java,
Response.java,
Survey.java but use
SEQ_AUTHORS with
SEQUENCE_AUTHORS,
SEQ_ITEMS with
SEQUENCE_ITEMS,
SEQ_QUESTIONS with
SEQUENCE_QUESTIONS,
SEQ_RESPONSES with
SEQUENCE_RESPONSES, and
SEQ_SURVEYS with
SEQUENCE_SURVEYS.
Step 4: Create a Session Facade
Click on
ModelEJB30 in the
Application Navigator. Any other entry of
the
ModelEJB30 project will do, also. Select
New... from the
Context
Menu and navigate to
Business Tier -> EJB in the
New Gallery. On the
right-hand side select
Session Bean and click on the
OK button to open a 6 step
Create Session Bean wizard.
- Since the EJB version is already known the wizard starts a step 2, by using the Back button you can go to step 1 but this is not needed.
- In step 2 change the EJB Name to SurveySession, accept the pre-selected
defaults and click on Next to go to the next wizard step.
- In step 3 make sure that all methods are checked (expand the tree to see
which methods are available). Click Next to go to the next wizard step.
- Step 4 shows the default values for the bean class and Step 5 - Click
Next to go from step 4 to step 5 - shows the implemented interfaces.
Remote and Local interfaces are good enough for our scenario. Clicking
Next in Step 5 directs us to the wizard Summary window which we close
by clicking on the Finish button.
A
SurveySessionBean will be added to
the project. Double-click on it and you'll see the generated Session
Facade in the Code Editor.
Step 5: Create a Test Client
To finish the JDeveloper 11g tasks, the creation of a test client
needs to be done. Click on the
SurveySessionBean in the
Application
Navigator and open the
Context Menu. Find the
New Sample Java Client
entry and click on it. Accept all default values and click on the
OK
button to generate the test client. Open it and change the
main method
as follows:
public static void main(String[] args) {
try {
final Context context = getInitialContext();
SurveySession surveySession =
(SurveySession)context.lookup("SurveySession");
Author author = new Author();
author.setName("Olaf Heimburger");
surveySession.persistEntity(author);
for (Author author :
(List<Author>)surveySession.queryAuthorFindAll()) {
System.out.println("id = " + author.getId());
System.out.println("name = " + author.getName());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
To test the Session Facade and the Test Client do the following:
-
Select the SurveySessionBean, open the Context Menu and select Run.
Wait until you see Embedded OC4J Server startup time: 83594 ms.
-
Select the SurveySessionClient, open the Context Menu and select Run.
What Have We Done So Far?
First of all we have created a number of
Entities for the
Tables that we created in the
Database project. Each
Entity has it's own
Sequence Generator assigned, using the
@GeneratedValue annotation. Since we used the default
SEQUENCE statement for the database, ie without an explicit
INCREMENT option, we had to adjust the default
allocationSize for JPA layer from
50 to
1 in the
@SequenceGenerator annotation. Finally we created a Session Facade for
persisting,
retrieving and
updating our
Entities conveniently. The very last step was to test the Facade with the Author class.
References
- EJB 3 in Action, Debu Panda, Reza Rahman, Derek Lane, Manning, ISBN 978-1-933988-34-4
- Java Persistence with Hibernate, Christian Bauer, Gavin King, Manning, ISBN 1-932394-88-5