Lab Exercises
For the sake of the simplicity of the lab, most exercises are provided in the form of “ready-to-open-and-run” NetBeans projects. (Many of them are borrowed from “glassfish-samples” and “Java EE 6 tutorial“.) Please feel free to create them from scratch if you want to.
It is strongly encouraged, leveraging what is provided in this lab, you do your own experimentation meaning creating/adding your own code as much as you can.
If you have written some code that might help everyone else, please feel free to share them on this codecamp email alias or directly send them to the instructors. Your name will be recognized in this lab if your sample code is chosen to be included. For the tasks that need to be done, please see the “Things to be done” section above.)
- Exercise 0: Build standalone JPA application step by step (30 minutes)
- Exercise 1: Mapping with @ElementCollection (30 minutes)
- Exercise 2: Mapping with @OrderColumn (30 minutes)
- Exercise 3: Map (30 minutes)
- Exercise 4: JPQL Improvements (20 minutes)
- Exercise 5: Criteria API without using Metamodel (30 minutes)
- Exercise 6: Criteria API using Metamodel (30 minutes)
- Exercise 7: Locking (30 minutes)
- Exercise 8: Caching API (10 minutes)
- Exercise 9: Build and run “order” sample application (30 minutes)
- Exercise 10: Build and run “roster” sample application (30 minutes)
- Homework Exercise
Exercise 0: Build standalone JPA application step by step
In this exercise, you are going to build a simple standalone (Java SE) JPA application step by step. Since many of the sample applications you are going to build and run in this lab are “ready to open and run” standalone applications, it would be useful for you to know how those applications were built.
(0.1) Start Java DB database server
1. Start Java DB database server.
- Select Services tab.
- Expand Databases.
- Right click Java DB and select Start Server.
Figure-0.11
(0.2) Build a simple “helloworld” standalone JPA application
- Select File from top-level menu and select New Project.
Figure-0.21
- Select Java under Categories on the left and Java Application under Projects on the right.
- Click Next.
Figure-0.22
- For the Project Name field, enter jpa2.0_helloworld (or whatever project name of your choice).
- Click Finish.
Figure-0.23
2. Create Person Entity class.
- Right click jpa20_helloworld package and select New->Java Class. (Or you can select Entity Class if it is in the pop-up menu.)
Figure-0.24
- For the Class Name field, enter Person.
- Click Finish.
Figure-0.25
- Modify IDE generated Person.java with the one below. Note that Person class is POJO class annotated with @Entity.
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package jpa20_helloworld; import javax.persistence.Entity; /** /** /** /** /** /** /** } |
- Observe that there are compile errors. This is expected because the libraries are not added yet to the project.
Figure-0.26
- Right click Libraries of the project and select Add Library.
Figure-0.27
- Observe that Add Library dialog box appears.
- Select EclipseLink(JPA2.0), EclipseLink-GlassFish-v3, Java DB Driver, Java-EE-GlassFish-v3 and click Add Library button.
Figure-0.28
- Observe that the compile errors are gone.
Trouble-shooting: If you don’t see Java DB Driver somehow, please add derbyclient.jar instead. (The Java DB Driver library is made of derbyclient.jar file.) The derbyclient.jar is available under GLASSFISH_HOME/javadb/lib directory. For your convenience, it is also provided under <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/clientdrivers directory. The step to take is right clicking Libraries and select Add JAR/Folder.
4. Create persistence unit (persistence.xml).
- Click Save all files… button so that the Person class be known to the persistence unit you are going to create.
- Right click project and select New->Other.
Figure-0.29
- Select Persistence under Categories on the left and select Persistence Unit under File Types on the right.
- Click Next.
Figure-0.30
- For Database Collection field, select jdbc:derby://localhost:1527/sample [app on APP]. This is to select sample database as an actual database for persistence operation. (The sample database is a built-in database that comes with GlassFish.)
- For Table Generation Strategy, select Drop and Create. When chosen, this strategy lets you drop existing tables and create new ones. Given that you are going to run this application multiple times, this is the most convenient table generation strategy.
- Click Finish.
Figure-0.31
5. Add Entity class to persistence unit.
- Click Add Class button on the section of Include Entity Classes section at the bottom.
Figure-0.32
- Select jpa20_helloworld.Person and click OK.
Figure-0.33
6. Modify Main.java as shown below. It creates two Person instances and persists them into the PERSON table in the sample database.
package jpa20_helloworld;
import javax.persistence.EntityManager; /** /** EntityTransaction tx = em.getTransaction(); Person p1 = new Person(); Person p2 = new Person(); tx.commit(); em.close(); } |
Main.java
6. Build and run the application.
- Right click project and select Run.
Figure-0.34
- Make sure the build has been successful.
Figure-0.35
Trouble-shooting: If you experience “..Person… is not a known entity type” error condition as shown below, it is because you have not added the Person class as entity class to the persistence.xml as described above.
Figure-0.36
Trouble-shooting: You will see the following [EL Warning] condition overtime you run the application – and the rest of the sample applications in this hands-on lab. This is expected and benign warning message. The reason you get this warning is because the ID generation strategy of the Person entity class is set with @GeneratedValue. What this means is you are asking the persistence provider to generate an ID for each newly created entry in the PERSON table. And the persistence provider is internally using SEQUENCE table for computing the next ID value. Now the persistence provider will try to create a new SEQUENCE table whenever the application is run but found that it already exists and displays a warning. If you delete SEQUENCE table manually, you will not see this warning, by the way, just as an experimentation.
[EL Warning]: 2010-01-14 10:57:09.204–ServerSession(27653945)–Exception [EclipseLink-4002] (Eclipse Persistence Services – 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLException: Table/View ‘SEQUENCE’ already exists in Schema ‘APP’. Error Code: -1 Call: CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT DECIMAL(15), PRIMARY KEY (SEQ_NAME)) |
Figure-0.37
7. Verify the PERSON table has been created.
- Click Services tab.
- Expand Databases.
- Right click jdbc:derby://localhost:1527/sample [app on APP] and select Connect.
Figure-0.38
- Expand App->Tables.
- Right click PERSON and select View Data.
Figure-0.39
- Verify that the PERSON table now has two entries.
Figure-0.40
8. Add JPAUtil class under jpa20_helloworld.util package. JPAUtil class is a collection of utility classes including checkData() method that displays the entries of a table.
package jpa20_helloworld.util;
import java.sql.Connection; public class JPAUtil { // Database configuration static { public static void setup(String sql) { public static void createStatement() { // Drop table if exists public void executeSQLCommand(String sql) throws Exception { public static void checkData(String sql) { public static void outputResultSet(ResultSet rs) throws Exception { int numcols = metadata.getColumnCount(); linewidth = 1; StringBuffer divider = new StringBuffer(linewidth); // Begin the table output with a divider line // The next line of the table contains the column labels. while (rs.next()) { } static void overwrite(StringBuffer b, int pos, String s) { |
JPAUtil.java
Figure-0.41
9. Modify Main.java to use checkData() method to display the entries of the table.
package jpa20_helloworld;
import javax.persistence.EntityManager; /** /** EntityTransaction tx = em.getTransaction(); Person p1 = new Person(); Person p2 = new Person(); tx.commit(); // Display the table em.close(); |
Main.java
10. Run the application again.
- Observe that the entries of the PERSON table gets displayed in the Output window.
Figure-0.42
11. Display context sensitive Javadoc on any JPA classes. Please use context sensitive Javadoc for any JPA classes you want to learn about moving forward.
- Right click the @Entity in the editor window and select Show Javadoc.
Figure-0.43
- Observe that Javadoc of the @Entity class appears in the browser.
Figure-0.44
Solution: The solution of this exercise is available as jpa2.0_helloworld project under <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/solutions. You can just open it and run it.
Summary
In this exercise, you have built a simple standalone Java SE application which uses persistence step by step.
Exercise 1: Mapping with @ElementCollection
In JPA 2.0, rich mapping capabilities are added. For example, an entity can have a collection of basic types or Embeddable’s. (In JPA 1.0, an entity can have a collection of only entity type.) An Embeddable can have another Embeddable and Embeddable can have a one-to-many relationship with entity type. In this exercise, you are going to exercise these new mapping features.
(1.1) Collection of basic type
In this example, you are going to see how an Employee entity can have a collection of a Skill, which is String type, through the usage of @ElementCollection annotation. You are going to build and run the application and then explore the code next.
1. Open jpa2.0_mapping_collection_basictypes NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Windows: If you unzipped the 4537_javaee6_jpa2.0.zip file under C:\handsonlabs directory, the directory to which you want to browse down should be C:\handsonlabs\javaee6_jpa2.0\samples.
- Solaris/Linux/Mac: If you unzipped the 4537_javaee6_jpa2.0.zip file under $HOME/handsonlabs directory, the directory to which you want to browse down should be $HOME/handsonlabs/javaee6_jpa2.0/samples.
- Select jpa2.0_mapping_collection_basictypes.
- Click Open Project.
- Observe that the jpa2.0_mapping_collection_basictypes project node appears under Projects tab window.
2. Build and run jpa2.0_mapping_collection_basictypes project.
- Right-click jpa2.0_mapping_collection_basictypes project and select Run.
- Observe the result in the Output window.
Figure-1.11
Figure-1.12
(1.2) Study code
- Observe that the Employee entity has a set of String basic type through the usage of @ElementCollection annotation.
Figure-1.21
package examples.model;
import java.util.Set; @Entity @Id // Collection of basic type – String type in this case public Employee() { public Employee(int id) { public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { @Override; /** /** |
Employee.java
2. persistence.xml.
- Note that the properties are now standardized in JPA 2.0. For example, instead of toplink.jdbc.driver for the Toplink or another name for another persistence provider, you are going to use standardized javax.persistence.jdbc.driver.
- Note that we are using drop-and-create-tables (Drop and Create tables) strategy, which means the persistence provider will drop existing EMPLOYEE and EXPERTISE tables and recreate them everytime you run the application.
Figure-1.22
<?xml version=”1.0″ encoding=”UTF-8″?> <persistence version=”1.0″ xmlns=”http://java.sun.com/xml/ns/persistence”> <persistence-unit name=”EmployeeService” transaction-type=”RESOURCE_LOCAL”> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>examples.model.Employee</class> <properties> <property name=”eclipselink.target-database” value=”DERBY”/> <!–<property name=”eclipselink.ddl-generation” value=”create-tables”/>–> <property name=”eclipselink.ddl-generation” value=”drop-and-create-tables”/> <property name=”eclipselink.logging.level” value=”INFO”/> <property name=”javax.persistence.jdbc.driver” value=”org.apache.derby.jdbc.ClientDriver”/> <property name=”javax.persistence.jdbc.url” value=”jdbc:derby://localhost:1527/sample”/> <property name=”javax.persistence.jdbc.user” value=”app”/> <property name=”javax.persistence.jdbc.password” value=”app”/> <property name=”” value=”app”/> </properties> </persistence-unit> </persistence> |
persistence.xml
3. Main.java.
- The Main class provides a testing code, in which a couple of Employee entities with a collection of String type are created. The contents of the database tables are then displayed so that you can tell if the tables are created and correct data are persisted.
package mypackage;
import examples.model.Employee; import examples.model.EmployeeService; import javax.persistence.EntityTransaction; public class Main { public static void main(String[] args) throws Exception { // Create EntityManager // EmployeeService is a utility class EntityTransaction tx = em.getTransaction(); Employee emp = es.createEmployee(“Sang Shin”, 10000); emp = es.createEmployee(“Bill Clinton”, 8000); es.createEmployee(“Angela Caicedo”, 6000); tx.commit(); // Display the table em.close(); } |
Main.java
4. EmployeeService.java. The EmployeeService class is utility class which provide a few convenience methods.
package examples.model;
import java.util.Collection; import javax.persistence.EntityManager; public class EmployeeService { protected EntityManager em; public EmployeeService(EntityManager em) { public Employee createEmployee(String name, long salary) { public Employee updateEmployee(Employee emp) { public void setJavaskills(Employee emp, Set<String> javaskills) { public void removeEmployee(int id) { public Employee raiseEmployeeSalary(int id, long raise) { public Employee findEmployee(int id) { public Collection<Employee> findAllEmployees() { |
EmployService.java
(1.3) Collection of Embeddable
1. Open jpa2.0_mapping_collection_embeddables NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_mapping_collection_embeddables.
- Click Open Project.
- Observe that the jpa2.0_mapping_collection_embeddables project node appears under Projects tab window.
2. Build and run jpa2.0_mapping_collection_embeddables project.
- Right-click jpa2.0_mapping_collection_embeddables project and select Run.
- Observe the result in the Output window.
Figure-1.31
(1.4) Study code
package examples.model;
import java.util.Set; @Entity @Id // Collection of basic type – String type in this case // Collection of embeddable type public Employee() { public Employee(int id) { public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { @Override; /** /** /** /** |
Employee.java
2. Address.java. Note that Address class is an Embeddable type.
package examples.model;
import java.io.Serializable; @Embeddable public Address(){ } public Address(String street, String city, String state) { /** /** /** /** /** /** |
Address.java
3. Main.java
package mypackage;
import examples.model.Address; import examples.model.EmployeeService; import javax.persistence.EntityTransaction; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); EntityTransaction tx = em.getTransaction(); es.createEmployee(“Sang Shin”, 10000); Set<Address> vacationHomes = new HashSet<Address>(); es.createEmployee(“Bill Clinton”, 8000); es.createEmployee(“Angela Caicedo”, 6000); tx.commit(); // Display the table em.close(); } |
Main.java
(1.5) Multi-level Embeddables
1. Open jpa2.0_mapping_collection_embeddables_multilevels NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_mapping_collection_embeddables_multilevels.
- Click Open Project.
- Observe that the jpa2.0_mapping_collection_embeddables_multilevels project node appears under Projects tab window.
2. Build and run jpa2.0_mapping_collection_embeddables_multilevels project.
- Right-click jpa2.0_mapping_collection_embeddables_multilevels project and select Run.
- Observe the result in the Output window.
Figure-1.51
(1.6) Study code
package examples.model;
import java.util.Set; @Entity @Id // Collection of basic type – Stting type in this case // Collection of embeddable type // Multi-levels of Embeddable public Employee() { public Employee(int id) { public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { @Override; /** /** /** /** /** /** |
Employee.java
2. ContactInfo.java.
package examples.model;
import java.io.Serializable; @Embeddable public ContactInfo(){ public ContactInfo(Address address) { /** /** } |
ContactInfo.java
3. Address.java
package examples.model;
import java.io.Serializable; @Embeddable public Address(){ } public Address(String street, String city, String state) { /** /** /** /** /** /** |
Address.java
4. Main.java.
package mypackage;
import examples.model.Address; import examples.model.EmployeeService; import javax.persistence.EntityTransaction; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); EntityTransaction tx = em.getTransaction(); // First employee Set<String> javaskills = new HashSet<String>(); Set<Address> vacationHomes = new HashSet<Address>(); ContactInfo contactInfo = new ContactInfo(new Address(“1 dreamland road”, “Newton”, “MA”)); // 2nd employee es.createEmployee(“Angela Caicedo”, 6000); tx.commit(); // Display the table em.close(); } |
Main.java
(1.7) Embeddable with its own relationship
1. Open jpa2.0_mapping_collection_embeddables_relation NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_mapping_collection_embeddables_relation.
- Click Open Project.
- Observe that the jpa2.0_mapping_collection_embeddables_relation project node appears under Projects tab window.
2. Build and run jpa2.0_mapping_collection_embeddables_relation project.
- Right-click jpa2.0_mapping_collection_embeddables_relation project and select Run.
- Observe the result in the Output window.
Figure-1.71
(1.8) Study code
package examples.model;
import java.io.Serializable; @Entity @Id // Multi-levels of Embeddable public Employee() { public Employee(int id) { public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { @Override; /** /** |
Employee.java
2. ContactInfo.java. Note that the ContactInfo class, which is@Embeddable type, has one-to-many bidirectional relationship with Phone entity class.
package examples.model;
import java.io.Serializable; @Embeddable // One-to-many bidirectional relationship between public ContactInfo(){ public ContactInfo(Address address) { /** /** /** /** } |
ContactInfo.java
3. Phone.java
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Id // Bi-directional one-to-many relationship public int getId() { public void setId(int id) { public Phone() { public Phone(String phoneNumber, Employee emp) { public Phone(int id, String phoneNumber) { public String getPhoneNumber() { /** /** /** |
Phone.java
4. Main.java
package mypackage;
import examples.model.Address; import examples.model.Employee; import javax.persistence.EntityTransaction; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); EntityTransaction tx = em.getTransaction(); // First employee // Second employee // Perform query – Retrieve all employees whose street is // Perform query – Retrieve all employees who have a specific phone number tx.commit(); // Display the table em.close(); } // Display the query result |
Main.java
Summary
In this exercise, you have explored richer mapping capabilities of JPA 2.0 through use of @ElementCollection.
Exercise 2: Mapping with @OrderColumn
JPA 2.0 adds support for an OrderColumn. An OrderColumn can be used to define an order List on any collection mapping. It is defined through the @OrderColumn annotation or <order-column> XML element.
The OrderColumn is maintained by the mapping and should not be an attribute of the target object. The table for the OrderColumn depends on the mapping. For a OneToMany mapping it will be in the target object’s table. For a ManyToMany mapping or a OneToMany using a JoinTable it will be in the join table. For an ElementCollection mapping it will be in the target table.
(2.0) Delete PHONE_TABLE manually (only if it exists)
The PHONE_TABLE has been created as a result of previous exercise. In running jpa2.0_mapping_ordercolumn_ElementCollection project, which you about to run, the persistence provider will try to delete and create EMPLOYEE table as instructed in the persistence.xml but will fail because the EMPLOYEE table has a dependency on the PHONE_TABLE table, hence the reason you will have to manually delete PHONE_TABLE first.
1. If you do not see the PHONE_TABLE, right-click on APP and select Refresh before deleting it.
- Right click Services tab.
- Right click APP and select Refresh.
Figure-2.01 – Refreshing the APP database to see the PHONE_TABLE
2. Delete PHONE_TABLE if it exists.
- Right click PHONE_TABLE and select Delete.
(2.1) @OrderColumn with a collection of basic type
1. Open jpa2.0_mapping_ordercolumn_ElementCollection NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_mapping_ordercolumn_ElementCollection.
- Click Open Project.
- Observe that the jpa2.0_mapping_ordercolumn_ElementCollection project node appears under Projects tab window.
2. Build and run jpa2.0_mapping_ordercolumn_ElementCollection project.
- Right-click jpa2.0_mapping_ordercolumn_ElementCollection project and select Run.
- Observe the result in the Output window.
Figure-2.11
(2.2) Study the code
package examples.model;
import java.util.List; @Entity @Id // Collection of basic type – Stting type in this case public Employee() { public Employee(int id) { public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { @Overrride /** /** |
2. Main.java
package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import javax.persistence.EntityTransaction; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); EntityTransaction tx = em.getTransaction(); Employee emp = es.createEmployee(“Sang Shin”, 10000); emp = es.createEmployee(“Bill Clinton”, 8000); es.createEmployee(“Angela Caicedo”, 6000); tx.commit(); // Display the table em.close(); } |
(2.3) @OrderColumn with one-to-many Unidirectional relationship
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_mapping_ordercolumn_OneToMany_Unidirection.
- Click Open Project.
- Observe that the jpa2.0_mapping_ordercolumn_OneToMany_Unidirection project node appears under Projects tab window.
2. Build and run jpa2.0_mapping_ordercolumn_OneToMany_Unidirection project.
- Right-click jpa2.0_mapping_ordercolumn_OneToMany_Unidirection project and select Run.
- Observe the result in the Output window.
Figure-2.31
(2.4) Study the code
package examples.model;
import java.util.List; @Entity @Id private String name; // Unidirectional One-to-Many association using a foreign key mapping public Employee() { public Employee(int id) { public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { public String toString() { /** /** |
(2.5) @OrderColumn with one-to-many Bidirectional relationship
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_mapping_ordercolumn_OneToMany_Bidirection.
- Click Open Project.
- Observe that the jpa2.0_mapping_ordercolumn_OneToMany_Bidirection project node appears under Projects tab window.
2. Build and run jpa2.0_mapping_ordercolumn_OneToMany_Bidirection project.
- Right-click jpa2.0_mapping_ordercolumn_OneToMany_Bidirection project and select Run.
- Observe the result in the Output window.
Figure-2.51
(2.6) Study the code
package examples.model;
import java.io.Serializable; @Entity @Id private String name; // Bidirectional one to many relationship through “mappedBy”. public Employee() { public Employee(int id) { public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { @Override /** /** |
Employee.java
2. Phone.java
package examples.model;
import java.io.Serializable; @Entity @Id // Bi-directional one-to-many relationship public int getId() { public void setId(int id) { public Phone() { public Phone(String phoneNumber, Employee emp) { public Phone(int id, String phoneNumber) { public String getPhoneNumber() { /** /** /** |
Phone.java
3. Main.java
package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import javax.persistence.EntityTransaction; public class Main { public static void main(String[] args) throws Exception { // Perform JPA operations // Create some employees EntityTransaction tx = em.getTransaction(); Employee emp = es.createEmployee(“Sang Shin”, 10000); emp = es.createEmployee(“Bill Clinton”, 8000); tx.commit(); // Display the table em.close(); } // Display the query result |
Main.java
Summary
In this exercise, you have explored how @OrderColumn is used to define an order List on any collection mapping.
Exercise 3: Map key
* A Basic value, stored in the target’s table or join table.
* An Embedded object, stored in the target’s table or join table.
* A foreign key to another Entity, stored in the target’s table or join table.
Map columns can be used for any collection mapping including, OneToMany, ManyToMany and ElementCollection.
(3.1) @MapKeyColumn
1. Open jpa2.0_mapping_MapKeyColumn NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_mapping_MapKeyColumn.
- Click Open Project.
- Observe that the jpa2.0_mapping_MapKeyColumn project node appears under Projects tab window.
2. Build and run jpa2.0_mapping_MapKeyColumn project.
- Right-click jpa2.0_mapping_MapKeyColumn project and select Run.
- Observe the result in the Output window.
Figure-3.11
(3.2) Study the code
package examples.model;
import java.io.Serializable; @Entity @Id private String name; // Bidirectional one to many relationship through “mappedBy”. public Employee() { public Employee(int id) { public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { @Override /** /** } |
Employee.java
2. Phone.java
package examples.model;
import java.io.Serializable; @Entity @Id // Bi-directional one-to-many relationship public int getId() { public void setId(int id) { public Phone() { public Phone(String phoneNumber, Employee emp) { public Phone(int id, String phoneNumber) { public String getPhoneNumber() { /** /** /** |
Phone.java.
3. Main.java
package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import javax.persistence.EntityTransaction; public class Main { public static void main(String[] args) throws Exception { // Perform JPA operations // Create some employees EntityTransaction tx = em.getTransaction(); Employee emp = es.createEmployee(“Sang Shin”, 10000); emp = es.createEmployee(“Bill Clinton”, 8000); tx.commit(); // Display the table em.close(); } // Display the query result |
Main.java
(3.3) @MapKeyClass
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_mapping_MapKeyClass.
- Click Open Project.
- Observe that the jpa2.0_mapping_MapKeyClass project node appears under Projects tab window.
2. Build and run jpa2.0_mapping_MapKeyClass project.
- Right-click jpa2.0_mapping_MapKeyClass project and select Run.
- Observe the result in the Output window.
Figure-3.31
(3.4) Study the code
package examples.model;
import java.io.Serializable; @Entity @Id private String name; // Bidirectional one to many relationship through “mappedBy”. public Employee() { public Employee(int id) { public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { @Override /** /** } |
Employee.java
2. Phone.java
package examples.model;
import java.io.Serializable; @Entity @Id // Bi-directional one-to-many relationship public int getId() { public void setId(int id) { public Phone() { public Phone(String phoneNumber) { public Phone(int id, String phoneNumber) { public String getPhoneNumber() { /** /** /** |
Phone.java
3. PhoneType.java
package examples.model;
import java.io.Serializable; @Embeddable @Basic public PhoneType() { public PhoneType(String type) { /** /** } |
PhoneType.java
4. Main.java
package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import javax.persistence.EntityTransaction; public class Main { public static void main(String[] args) throws Exception { // Perform JPA operations // Create some employees EntityTransaction tx = em.getTransaction(); Employee emp = es.createEmployee(“Sang Shin”, 10000); emp = es.createEmployee(“Bill Clinton”, 8000); tx.commit(); // Display the table em.close(); } // Display the query result |
Main.java
Summary
In this exercise, you have explored how to use different kinds of Map key.
Exercise 4: JPQL Impovements
(4.1) INDEX
0. Delete EMPLOYEE_PHONE_TABLE manually.
The EMPLOYEE_PHONE_TABLE has been created as a result of previous exercise. In running jpa2.0_jpql_index project, the persistence provider will try to delete and create EMPLOYEE table as instructed in the persistence.xml but will fail because it has a dependency on the EMPLOYEE_PHONE_TABLE, hence the reason you will have to manually delete PHONE_TABLE first.
If you do not see the EMPLOYEE_PHONE_TABLE, right-click on APP and select Refresh before deleting it.
1. Open jpa2.0_jpql_index NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_jpql_index.
- Click Open Project.
- Observe that the jpa2.0_jpql_index project node appears under Projects tab window.
2. Build and run jpa2.0_jpql_index project.
- Right-click jpa2.0_jpql_index project and select Run.
- Observe the result in the Output window.
Figure-4.11
—— Query result of “SELECT e FROM Employee e INNER JOIN e.phones p WHERE e.name = ‘Sang Shin’ AND INDEX(p) < 3 ” Employee 1, Sang Shin, 10000 Employee 1, Sang Shin, 10000 Employee 1, Sang Shin, 10000 —— Query result of “SELECT DISTINCT e FROM Employee e INNER JOIN e.phones p WHERE e.name = ‘Sang Shin’ AND INDEX(p) < 3 ” —— Query result of “SELECT e FROM Employee e INNER JOIN e.phones p WHERE e.name = ‘Sang Shin’ AND INDEX(p) < 1 ” —— Query result of “SELECT DISTINCT e FROM Employee e INNER JOIN e.phones p WHERE INDEX(p) BETWEEN 0 AND 4 ” |
(4.2) Study the code
@package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import javax.persistence.EntityTransaction; public class Main { public static void main(String[] args) throws Exception { // Perform JPA operations // Create some employees EntityTransaction tx = em.getTransaction(); Employee emp = es.createEmployee(“Sang Shin”, 10000); emp = es.createEmployee(“Bill Clinton”, 8000); tx.commit(); // Display the table // Usage of INDEX example Query query = em.createQuery(jpql); // Usage of INDEX example query = em.createQuery(jpql); // Usage of INDEX example query = em.createQuery(jpql); // Usage of INDEX example query = em.createQuery(jpql); em.close(); } // Display the query result |
Main.java
(4.3) CASE
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_jpql_case.
- Click Open Project.
- Observe that the jpa2.0_jpql_case project node appears under Projects tab window.
2. Build and run jpa2.0_jpql_case project.
- Right-click jpa2.0_jpql_case project and select Run.
- Observe the result in the Output window.
Figure-4.31
(4.4) Study the code
package mypackage;
import javax.persistence.EntityManager; import examples.model.EmployeeService; import javax.persistence.Query; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); em.getTransaction().begin(); // Display the table // Use CASE em.getTransaction().begin(); // Display the table em.close(); } // Display the query result |
Main.java
Summary
In this exercise, you have explored some new keywords that are added to JPQL, especially INDEX and CASE.
Exercise 5: Criteria API (without using Metamodel)
The Criteria API and JPQL are closely related, and designed to allow similar operations in their queries. Developers familiar with JPQL syntax will find equivalent object-level operations in the Criteria API.
The basic semantics of a Criteria query consists of a select clause, a from clause, and an optional where clause, similar to a JPQL query. Criteria queries set these clauses using Java programming language objects, so the query can be created in a type-safe manner.
Please read Basic Type-Safe Queries Using the Criteria API and Metamodel API section of the Java EE 6 tutorial before you do this exercise.
(5.1) Criteria API with “where” method
0. Delete PHONE_TABLE and EMPLOYEE tables.
1. Open jpa2.0_criteria_where NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_criteria_where.
- Click Open Project.
- Observe that the jpa2.0_criteria_where project node appears under Projects tab window.
2. Build and run jpa2.0_criteria_where project.
- Right-click jpa2.0_criteria_where project and select Run.
- Observe the result in the Output window.
Figure-5.11
—— Query result of “SELECT e FROM Employee e” Employee 3, Angela Caicedo, 6000 Employee 5, Charles Song, 4500 Employee 1, Sang Shin, 10000 Employee 4, Annie Song, 5000 Employee 2, Bill Clinton, 8000 ******* Query result using Criteria API —— Query result of “SELECT e FROM Employee e where e.name = ‘Sang Shin'” ******* Query result using Criteria API —— Query result of “SELECT e FROM Employee e where e.name = ‘Sang Shin’ OR e.salary > 7000” ******* Query result using Criteria API —— Query result of “SELECT e FROM Employee e where e.name LIKE ‘A%'” ******* Query result using Criteria API —— Query result of “SELECT e FROM Employee e where e.name IN (‘Sang Shin’, ‘Bill Clinton’, ‘Some name’)” ******* Query result using Criteria API |
(5.2) Study code
package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import util.JPAUtil; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); em.getTransaction().begin(); // Display the table // Get all employees whose name is ‘Sang Shin’ ///////// Perform the same query using Criteria API // —- Build criteria // —- Create a query object from Criteria and perform query operation // —- Display the result // Get all employees whose name is ‘Sang Shin’ ///////// Perform the same query using Criteria API // —- Build criteria // —- Create a query object from Criteria and perform query operation // —- Display the result // Get all employees whose name is ‘Sang Shin’ or whose salary is greater than 7000 ///////// Perform the same query using Criteria API // Get all emplyees whose name starts with A ///////// Perform the same query using Criteria API // Get all employees whose name is either ‘Sang Shin’ or ‘Bill Clinton” or ‘Some name’ ///////// Perform the same query using Criteria API em.close(); } // Display the query result // Display the query result |
2. Display and study Javadoc of CriteriaQuery.
(5.3) Criteria API with “orderBy” method
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_criteria_order_by.
- Click Open Project.
- Observe that the jpa2.0_criteria_order_by project node appears under Projects tab window.
2. Build and run jpa2.0_criteria_order_by project.
- Right-click jpa2.0_criteria_order_by project and select Run.
- Observe the result in the Output window.
Figure-5.31
(5.4) Study code
package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import javax.persistence.Query; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); EntityTransaction tx = em.getTransaction(); es.createEmployee(“Sang Shin”, 10000); tx.commit(); // Display the table // Perform JPA query with ORDER BY ///////// Perform the same query using Criteria API // Create criteria // Create query using Criteria and then perform query operation em.close(); } // Display the query result // Display the query result |
Main.java
(5.5) Criteria API with relationship traversal
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_criteria_relation_traversal.
- Click Open Project.
- Observe that the jpa2.0_criteria_relation_traversal project node appears under Projects tab window.
2. Build and run jpa2.0_criteria_relation_traversal project.
- Right-click jpa2.0_criteria_relation_traversal project and select Run.
- Observe the result in the Output window.
Figure-5.51
(5.6) Study code
package mypackage;
import customer.model.Customer; import java.util.List; import javax.persistence.Query; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = // Display the test table // Display all customers whose discount rate is bigger than 10% ///////// Perform the same query using Criteria API // Create criteria // Create query using Criteria and then perform query operation em.close(); } // Display the query result // Display the query result |
(5.7) Criteria API with inner join
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_criteria_relation_innerjoin.
- Click Open Project.
- Observe that the jpa2.0_criteria_relation_innerjoin project node appears under Projects tab window.
2. Build and run jpa2.0_criteria_relation_innerjoin project.
- Right-click jpa2.0_criteria_relation_innerjoin project and select Run.
- Observe the result in the Output window.
Figure-5.71
(5.8) Study code
package mypackage;
import javax.persistence.EntityManager; import java.util.List; import javax.persistence.Query; public class Main { public static void main(String[] args) throws Exception { // Display the test table // Perform JPA operations // Display all manufacturers who have products whose markups are greater than 20.0 – same as above ///////// Perform the same query using Criteria API // Create criteria // Create query using Criteria and then perform query operation em.close(); } // Display the query result // Display the query result } |
Main.java
Summary
In this exercise, you have explored how to use Criteria API to define queries through the construction of object-based query definition objects, rather than use of the string-based approach of the Java Persistence query language, thus providing type-safe, and portable queries that work regardless of the underlying data store.
Exercise 6: Criteria API (using Metamodel)
static
(and public
). The Person_.age
is one such static member variable. You instantiate the canonical class by generating a concrete Person_.java
at a source-code level at development time. Through such instantiation, it is possible to refer to persistent attributes of Person
at compile time, rather than at run time, in a strongly typed manner.
This Person
_ metamodel class is an alternative means of referring to meta information of Person
. This alternative is similar to the much-used (some may say, abused) Java Reflection API, but with a major conceptual difference. You can use reflection to obtain the meta information about an instance of a java.lang.Class
, but meta information about Person.class
cannot be referred to in a way that a compiler can verify. For example, using reflection, you’d refer to the field named age
in Person.class
with:
(6.1) Open, build, and run “jpa2.0_criteria_where_metamodel1_getMetaModel” sample application
1. Open jpa2.0_criteria_where_metamodel1_getMetaModel NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_criteria_where_metamodel1_getMetaModel.
- Click Open Project.
- Observe that the jpa2.0_criteria_where_metamodel1_getMetaModel project node appears under Projects tab window.
2. Build and run jpa2.0_criteria_where_metamodel1_getMetaModel project.
- Right-click jpa2.0_criteria_where_metamodel1_getMetaModel project and select Run.
- Observe the result in the Output window. Note that this is the same result you see when you ran jpa2.0_criteria_where project.
Figure-6.11
(6.2) Study code
package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import util.JPAUtil; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); em.getTransaction().begin(); // Display the table // Get all employees whose name is ‘Sang Shin’ ///////// Perform the same query using Criteria API // Use Metamodel – Obtaining a Metamodel Class Dynamically Using the Metamodel.getMetamodel Method // —- Build criteria // —- Create a query object from Criteria and perform query operration // —- Display the result // Get all employees whose name is ‘Sang Shin’ ///////// Perform the same query using Criteria API // —- Build criteria // —- Create a query object from Criteria and perform query operration // —- Display the result // Get all employees whose name is ‘Sang Shin’ or whose salary is greater than 7000 ///////// Perform the same query using Criteria API // Get all emplyees whose name starts with A ///////// Perform the same query using Criteria API // Get all employees whose name is either ‘Sang Shin’ or ‘Bill Clinton” or ‘Some name’ ///////// Perform the same query using Criteria API em.close(); } // Display the query result // Display the query result |
Main.java
(6.3) Open, build, and run “jpa2.0_criteria_where_metamodel2_Root_getModel” sample application
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_criteria_where_metamodel2_Root_getModel.
- Click Open Project.
- Observe that the jpa2.0_criteria_where_metamodel2_Root_getModel project node appears under Projects tab window.
2. Build and run jpa2.0_criteria_where_metamodel2_Root_getModel project.
- Right-click jpa2.0_criteria_where_metamodel2_Root_getModel project and select Run.
- Observe the result in the Output window. Note that this is the same result you see when you ran jpa2.0_criteria_where project.
Figure-6.31
(6.4) Study code
package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import util.JPAUtil; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); em.getTransaction().begin(); // Display the table // Get all employees whose name is ‘Sang Shin’ ///////// Perform the same query using Criteria API // Use Metamodel – Obtaining a Metamodel Class Dynamically Using the Root<T>.getModel Method // —- Build criteria // —- Create a query object from Criteria and perform query operration // —- Display the result // Get all employees whose name is ‘Sang Shin’ ///////// Perform the same query using Criteria API // —- Build criteria // —- Create a query object from Criteria and perform query operration // —- Display the result // Get all employees whose name is ‘Sang Shin’ or whose salary is greater than 7000 ///////// Perform the same query using Criteria API // Get all emplyees whose name starts with A ///////// Perform the same query using Criteria API // Get all employees whose name is either ‘Sang Shin’ or ‘Bill Clinton” or ‘Some name’ ///////// Perform the same query using Criteria API em.close(); } // Display the query result // Display the query result |
Main.java
Summary
In this exercise, you have explored how to use Criteria API with metamodel class.
Exercise 7: Locking
The Version attribute will be incremented with a successful commit. The Version attribute can be an int, short, long, or timestamp.
Pessimistic concurrency locks the database row when data is read, this is the equivalent of a (SELECT . . . FOR UPDATE [NOWAIT]) . Pessimistic locking ensures that transactions do not update the same entity at the same time, which can simplify application code, but it limits concurrent access to the data which can cause bad scalability and may cause deadlocks. Pessimistic locking is better for applications with a higher risk of contention among concurrent transactions.
(7.1) Open, build, and run “locking” sample application (from “glassfish-samples”)
1. Open locking NetBeans project (from “glassfish samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/jpa directory directory.
- Select locking.
- Click Open Project.
Figure-7.11
- Observe that the locking project node appears under Projects tab window.
2. Check the path to your server application installation.
- Browse to <GlassFish-v3-Installation-Directory>/glassfish/samples/bp-project directory and
open build.properties file with a text editor. - Check that in the second line javaee.home is set to the directory where GlassFish is installed.
For example, on a standard Mac OS X installation, it should be set to: /Applications/NetBeans
3. Build and run locking project.
- Right-click locking project and select Run.
- Observe the result in the Output window.
locking-test.runjavaclient: LockingJavaClient: Test is starting Calling URL:http://localhost:8080/locking/test/?tc=initData&nc=6&ns=3&np=3 Starting parallel updates with 9 users for operation: updateWOL Starting parallel updates with 9 users for operation: updateWPL |
Figure-7.12
(7.2) Study the code
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only (“GPL”) or the Common Development * and Distribution License(“CDDL”) (collectively, the “License”). You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. * Sun designates this particular file as subject to the “Classpath” exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: “Portions Copyrighted [year] * [name of copyright owner]” * * Contributor(s): * * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding “[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license.” If you don’t indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package enterprise.locking.entity; import javax.persistence.*; @Entity // Instance variables public Part() { public Part(int id, String name) { public Part(int id, String name, int amount) { // ================================================== @Id public void setId(int id) { @Column(length = 20, name = “PNAME”) public void setName(String name) { @Column(name = “AMOUNT”) public void setAmount(int amount) { @Version public void setVerNum(int verNum) { // =========================================================== public void setUsers(Set<User> users) { public String toString() { } |
enterprise.locking.entity.Part.java
Figure-7.21
Figure-7.22
2. User.java
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only (“GPL”) or the Common Development * and Distribution License(“CDDL”) (collectively, the “License”). You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. * Sun designates this particular file as subject to the “Classpath” exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: “Portions Copyrighted [year] * [name of copyright owner]” * * Contributor(s): * * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding “[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license.” If you don’t indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package enterprise.locking.entity; import javax.persistence.*; @Entity private int id; public User() { public User(int id, String firstName, String lastName) { public User(int id, String firstName, String lastName, UserType userType) { //======================================================= public void setId(int id) { @Column(length = 20, name = “FNAME”) public void setFirstName(String firstName) { @Column(length = 20, name = “LNAME”) public void setLastName(String lastName) { @Column(name = “UTYPE”) public void setUserType(UserType userType) { @Column(name = “COUNT”) public void setCount(int count) { // =========================================================== public void setPart(Part part) { public String toString() { } |
User.java
3. StatelessSessionBean.java
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only (“GPL”) or the Common Development * and Distribution License(“CDDL”) (collectively, the “License”). You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. * Sun designates this particular file as subject to the “Classpath” exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: “Portions Copyrighted [year] * [name of copyright owner]” * * Contributor(s): * * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding “[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license.” If you don’t indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package enterprise.locking.ejb; import enterprise.locking.entity.Part; import javax.ejb.Stateless; @Stateless @PersistenceContext private String name = “foo”; public String getName() { public void setName(String name) { /** for (int i = 0; i < numberOfParts; i++) { int partIndex = 1; for (int i = 0; i < numberOfSuppliers; i++) { /** // Simulate think time to allow parallel threads to find Usrs in parallel. try { /** User u = em.find(User.class, uID); // Simulate think time to allow parallel threads to find in parallel. try { } public void simulateThinkTimeForSecond(int sec) { } |
StatelessSessionBean.java
Summary
In this exercise, you have experimented with both optimistic locking and pessimistic locking.
(8.1) Open, build, and run “jpa2.0_cache” sample application
1. Open jpa2.0_cache NetBeans project (from “Lab samples”).
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_jpa2.0/samples directory.
- Select jpa2.0_cache.
- Click Open Project.
- Observe that the jpa2.0_cache project node appears under Projects tab window.
2. Build and run jpa2.0_cache project.
- Right-click jpa2.0_cache project and select Run.
- Observe the result in the Output window.
Figure-8.11
(8.2) Study code
package mypackage;
import javax.persistence.EntityManager; import examples.model.Employee; import util.JPAUtil; public class Main { public static void main(String[] args) throws Exception { EntityManagerFactory emf = EmployeeService es = new EmployeeService(em); em.getTransaction().begin(); // Display the table // Get all employees whose name is ‘Sang Shin’ // Get all employees whose name is ‘Sang Shin’ // Perform cache operations em.close(); } // Display the query result |
Main.java
2. Employee.java
package examples.model;
import javax.persistence.Column; @Entity public Employee() {} public int getId() { public void setId(int id) { public String getName() { public void setName(String name) { public long getSalary() { public void setSalary(long salary) { @Overrride |
Employee.java
Summary
In this exercise, you have explored with newly introduced Caching API.
(9.1) Open, build, and run “order” sample application (from “Java EE 6 tutorial”)
1. Open order NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <GlassFish-v3-Installation-Directory>/glassfish/docs/javaee-tutorial/examples/persistence directory. (This is “Java EE 6 tutorial” examples.)
- Select order.
- Click Open Project.
Figure-9.11
- Observe that the order project node appears under Projects tab window.
2. Change the Relative URL to order.xhtml. (This is the URL that gets accessed when the application starts.) If you don’t take this step, the application will try to display index.xhtml, which does not exist.
Figure-9.12
Figure-9.13
3. Build and run order project.
- Right-click order project and select Run.
- Observe that browser gets displayed.
Figure-9.14
Figure-9.15
Figure-9.16
Figure-9.17
Figure-9.18
Figure-9.19
Figure-9.20
Figure-9.21
(9.2) Control flow of “viewing all orders”
1. The order.xhtml is accessed. The #{orderManager.orders} calls getOrders() method of the OrderManager class.
… <h:dataTable var=”order” value=”#{orderManager.orders}” rules=”all” cellpadding=”5″> <h:column> <f:facet name=”header”> <h:outputText value=”Order ID” /> </f:facet> <h:form> <h:commandLink id=”order_id_link” action=”lineItem”> <h:outputText value=”#{order.orderId}” /> <f:setPropertyActionListener target=”#{orderManager.currentOrder}” value=”#{order.orderId}” /> </h:commandLink> </h:form> </h:column> <h:column> <f:facet name=”header”> <h:outputText value=”Shipment Info” /> </f:facet> <h:outputText value=”#{order.shipmentInfo}” /> </h:column> <h:column> <f:facet name=”header”> <h:outputText value=”Status” /> </f:facet> <h:outputText value=”#{order.status}” /> </h:column> <h:column> <f:facet name=”header”> <h:outputText value=”Last Updated” /> </f:facet> <h:outputText value=”#{order.lastUpdate}” /> </h:column> <h:column> <f:facet name=”header”> <h:outputText value=”Discount” /> </f:facet> <h:outputText value=”#{order.discount}%” /> </h:column> <h:column> <f:facet name=”header”> <h:outputText value=”Actions” /> </f:facet> <h:form> <h:commandLink value=”Delete” actionListener=”#{orderManager.removeOrder}” action=”order”> <f:param name=”deleteOrderId” value=”#{order.orderId}” /> </h:commandLink> </h:form> </h:column> </h:dataTable> … |
order.xhtml
2. The getOrders() method of the OrderManager class calls getOrders() method of the RequestBean class. Note that the RequestBean is injected.
… @ManagedBean @SessionScoped public class OrderManager { private static Logger logger = Logger.getLogger(“order.web.OrderManager”); private Boolean findVendorTableDisabled = true; private Boolean partsTableDisabled = true; private Integer currentOrder; private Integer newOrderId; private List<Part> newOrderParts; private List<Part> newOrderSelectedParts; private List<Order> orders; private List<String> vendorSearchResults; private Long selectedVendorPartNumber; @EJB private RequestBean request; private String newOrderShippingInfo; private String selectedPartNumber; private String vendorName; private char newOrderStatus; private int newOrderDiscount; private int selectedPartRevision; /** return orders; |
OrderManager.java
3. The getOrders() method of the RequestBean class calls a Named query called “findAllOrders”, which is defined in the Order class.
… public List<Order> getOrders() { try { return (List<Order>) em.createNamedQuery(“findAllOrders”) .getResultList(); } catch (Exception e) { throw new EJBException(e.getMessage()); } } … |
RequestBean.java
4. The “findAllOrders” Named query performs JPQL “SELECT o FROM Order o ORDER BY o.orderId”.
… @Entity @Table(name = “PERSISTENCE_ORDER_ORDER”) @NamedQuery(name = “findAllOrders”, query = “SELECT o FROM Order o ” + “ORDER BY o.orderId”) public class Order implements java.io.Serializable { private Collection<LineItem> lineItems; private Date lastUpdate; private Integer orderId; private String shipmentInfo; private char status; private int discount; public Order() { |
Order.java
(9.3) Control flow of “creating an order”
1. The submitOrder(..) method of the OrderManager class is invoked when a user submits an order.
… <ui:define name=”newOrderForm”> <h:form> <h:outputLabel for=”orderIdInputText” rendered=”true” value=”Order ID: ” /> <h:inputText id=”orderIdInputText” required=”true” value=”#{orderManager.newOrderId}” /><br /> <h:outputLabel for=”shipmentInfoInputText” rendered=”true” value=”Shipment Info: ” /> <h:outputLabel for=”statusMenu” rendered=”true” value=”Status: ” /> <h:outputLabel for=”discountMenu” rendered=”true” value=”Discount: ” /> <h:commandButton value=”Submit” action=”#{orderManager.submitOrder}” /> </ui:define> |
order.xhtml
2. The submitOrder() method calls createOrder(..) method of the RequestBean class.
… @EJB private RequestBean request; … public void submitOrder() { try { request.createOrder( newOrderId, newOrderStatus, newOrderDiscount, newOrderShippingInfo); logger.info( |
OrderManager.java
3. The createOrder(..) method of the RequestBean creates an order and persists it.
… public void createOrder( Integer orderId, char status, int discount, String shipmentInfo) { try { Order order = new Order(orderId, status, discount, shipmentInfo); em.persist(order); } catch (Exception e) { throw new EJBException(e.getMessage()); } } … |
RequestBean.java
Summary
In this exercise, you have explored with the “order” sample application that comes with Java EE 6 tutorial.
Exercise 10: Build and run “roster” sample application (from “Java EE 6 tutorial”)
(10.1) Open, build, and run “roster” sample application (from “Java EE 6 tutorial”)
1. Open roster NetBeans project.
- Select File->Open Project (Ctrl+Shift+O).
- Observe that the Open Project dialog box appears.
- Browse down to <GlassFish-v3-Installation-Directory>/glassfish/docs/javaee-tutorial/examples/persistence directory. (This is “Java EE 6 tutorial” examples.)
- Select roster.
- Check Open Required Projects
- Click Open Project.
2. Open required projects.
- Observe that the roster-app-client and roster-ejb projects are opened.
3. Build and run roster project.
- Right-click roster project and select Run.
- Observe the result in the Output window.
Figure-10.11
(10.2) Study “roster-app-client” project
1. RosterClient.java
Figure-10.21
/* * Copyright 2009 Sun Microsystems, Inc. * All rights reserved. You may not modify, use, * reproduce, or distribute this software except in * compliance with the terms of the License at: * http://developer.sun.com/berkeley_license.html */ package roster.client; import java.util.Iterator; public class RosterClient { public RosterClient(String[] args) { public static void main(String[] args) { try { System.exit(0); private void insertInfo() { // Teams request.createTeamInLeague( request.createTeamInLeague( request.createTeamInLeague( // Players, Team T1 request.createPlayer(“P2”, “Alice Smith”, “defender”, 505.00); request.createPlayer(“P3”, “Bob Roberts”, “midfielder”, 65.00); request.createPlayer(“P4”, “Grace Phillips”, “forward”, 100.00); request.createPlayer(“P5”, “Barney Bold”, “defender”, 100.00); // Players, Team T2 request.createPlayer( request.createPlayer(“P8”, “Anne Anderson”, “forward”, 65.00); request.createPlayer(“P9”, “Jan Wesley”, “defender”, 100.00); request.createPlayer(“P10”, “Terry Smithson”, “midfielder”, 100.00); // Players, Team T3 request.createPlayer( request.createPlayer( request.createPlayer( request.createPlayer(“P15”, “Candace Lewis”, “point guard”, 100.00); // Players, Team T4 request.createPlayer( request.createPlayer(“P18”, “Nancy White”, “small forward”, 833.00); request.createPlayer(“P19”, “Billy Black”, “power forward”, 444.00); request.createPlayer(“P20”, “Jodie James”, “point guard”, 100.00); // Players, Team T5 request.createPlayer(“P22”, “Janice Walker”, “defender”, 857.00); request.createPlayer( request.createPlayer(“P24”, “Gloria Garber”, “forward”, 777.00); request.createPlayer(“P25”, “Frank Fletcher”, “defender”, 399.00); // Players, Team T9 request.createPlayer(“P31”, “Mariela Prieto”, “freestyle”, 420.00); // Players, Team T10 request.createPlayer(“P33”, “Andre Gerson”, “freestyle”, 396.00); request.createPlayer(“P34”, “Zoria Lepsius”, “downhill”, 431.00); // Players, no team // Players, multiple teams // Adding existing players to second soccer league private void getSomeInfo() { System.out.println(“List all players in team T2:”); System.out.println(“List all teams in league L1:”); System.out.println(“List all defenders:”); System.out.println(“List the leagues of player P28”); private void getMoreInfo() { System.out.println(“Details of league L1:”); System.out.println(“Details of team T3:”); System.out.println(“Details of player P20:”); System.out.println(“List all teams in league L3:”); System.out.println(“List all players:”); System.out.println(“List all players not on a team:”); System.out.println(“Details of Jack Patterson, a power forward:”); System.out.println(“List all players in the city of Truckee:”); System.out.println(“List all soccer players:”); System.out.println(“List all players in league L1:”); System.out.println( System.out.println( System.out.println(“List all players of team T5:”); System.out.println(“List all the leagues of player P28:”); System.out.println(“List all the sports of player P28:”); private void removeInfo() { System.out.println(“Removing player P24”); private static void printDetailsList(List list) { while (i.hasNext()) { System.out.println(details.toString()); System.out.println(); |
RosterClient.java
2. See the properties of the roster-app-client project.
- Right click the roster-app-client project and select Properties.
- Click Libraries on the left and observe that roster-ejb.jar is in its class path.
Figure-10.22
- Click Run on the left and observe that the roster.client.RosterClient is the Main class meaning main() method of the class gets executed when the project is run.
Figure-10.23
(10.3) Study “roster-ejb” project
/* * Copyright 2009 Sun Microsystems, Inc. * All rights reserved. You may not modify, use, * reproduce, or distribute this software except in * compliance with the terms of the License at: * http://developer.sun.com/berkeley_license.html */ package roster.request; import java.util.List; @Remote void createLeague(LeagueDetails leagueDetails); void createPlayer( void createTeamInLeague( void dropPlayer( List<PlayerDetails> getAllPlayers(); LeagueDetails getLeague(String leagueId); List<LeagueDetails> getLeaguesOfPlayer(String playerId); PlayerDetails getPlayer(String playerId); List<PlayerDetails> getPlayersByCity(String city); List<PlayerDetails> getPlayersByHigherSalary(String name); List<PlayerDetails> getPlayersByLeagueId(String leagueId); List<PlayerDetails> getPlayersByPosition(String position); List<PlayerDetails> getPlayersByPositionAndName( List<PlayerDetails> getPlayersBySalaryRange( List<PlayerDetails> getPlayersBySport(String sport); List<PlayerDetails> getPlayersNotOnTeam(); List<PlayerDetails> getPlayersOfTeam(String teamId); List<String> getSportsOfPlayer(String playerId); TeamDetails getTeam(String teamId); List<TeamDetails> getTeamsOfLeague(String leagueId); void removeLeague(String leagueId); void removePlayer(String playerId); void removeTeam(String teamId); |
Request.java
2. RequestBean.java.
/* * Copyright 2009 Sun Microsystems, Inc. * All rights reserved. You may not modify, use, * reproduce, or distribute this software except in * compliance with the terms of the License at: * http://developer.sun.com/berkeley_license.html */ package roster.request; import java.util.ArrayList; /** @PostConstruct public void createPlayer( try { public void addPlayer( try { team.addPlayer(player); public void removePlayer(String playerId) { try { Collection<Team> teams = player.getTeams(); while (i.hasNext()) { em.remove(player); … public List<PlayerDetails> getPlayersByPosition(String position) { List<Player> players = null; try { if (cq != null) { // Get MetaModel from Root // set the where clause TypedQuery<Player> q = em.createQuery(cq); return copyPlayersToDetails(players); public List<PlayerDetails> getPlayersByHigherSalary(String name) { List<Player> players = null; try { if (cq != null) { // Get MetaModel from Root // create a Predicate object that finds players with a salary // create a Predicate object that finds the player based on TypedQuery<Player> q = em.createQuery(cq); return copyPlayersToDetails(players); public List<PlayerDetails> getPlayersBySalaryRange( List<Player> players = null; try { if (cq != null) { // Get MetaModel from Root // set the where clause TypedQuery<Player> q = em.createQuery(cq); return copyPlayersToDetails(players); public List<PlayerDetails> getPlayersByLeagueId(String leagueId) { List<Player> players = null; try { if (cq != null) { // Get MetaModel from Root // set the where clause TypedQuery<Player> q = em.createQuery(cq); return copyPlayersToDetails(players); public List<PlayerDetails> getPlayersBySport(String sport) { List<Player> players = null; try { if (cq != null) { // Get MetaModel from Root // set the where clause TypedQuery<Player> q = em.createQuery(cq); return copyPlayersToDetails(players); public List<PlayerDetails> getPlayersByCity(String city) { List<Player> players = null; try { if (cq != null) { // Get MetaModel from Root // set the where clause TypedQuery<Player> q = em.createQuery(cq); return copyPlayersToDetails(players); public List<PlayerDetails> getAllPlayers() { List<Player> players = null; try { if (cq != null) { cq.select(player); TypedQuery<Player> q = em.createQuery(cq); return copyPlayersToDetails(players); public List<PlayerDetails> getPlayersNotOnTeam() { List<Player> players = null; try { if (cq != null) { // Get MetaModel from Root // set the where clause TypedQuery<Player> q = em.createQuery(cq); return copyPlayersToDetails(players); public List<PlayerDetails> getPlayersByPositionAndName( List<Player> players = null; try { if (cq != null) { // Get MetaModel from Root // set the where clause TypedQuery<Player> q = em.createQuery(cq); return copyPlayersToDetails(players); public List<LeagueDetails> getLeaguesOfPlayer(String playerId) { List<LeagueDetails> detailsList = new ArrayList<LeagueDetails>(); try { if (cq != null) { //EntityType<League> League_ = league.getModel(); //EntityType<Team> Team_ = team.getModel(); cq.where( TypedQuery<League> q = em.createQuery(cq); Iterator<League> i = leagues.iterator(); while (i.hasNext()) { return detailsList; public List<String> getSportsOfPlayer(String playerId) { List<String> sports = new ArrayList<String>(); try { if (cq != null) { // Get MetaModel from Root // set the where clause TypedQuery<String> q = em.createQuery(cq); // Player player = em.find(Player.class, playerId); return sports; … |
2. Generated Metamodel classes
Summary
In this exercise, you have explored the “roster” sample application that comes with Java EE 6 tutorial.
Homework Exercise
- Exercise point: Mapping with @ElementCollection
- School entity class have schoolname field, which is String type, and district field, which is District class. See a snippet of the School class below.
… @Entity public class School implements Serializable { @Id private District district; |
- The District class is Embeddable type and has a set of Student’s. It also has districtname field, which is String type. See a snippet of District class below.
… @Embeddable public class District implements Serializable{ private String districtname; @OneToMany(cascade=CascadeType.ALL, mappedBy=”school”) |
- The Student class is an entity class and has studentname field, which is String type, and grade field, which is double type. See a snippet of Student class below.
… @Entity @Table(name = “STUDENT_TABLE”) public class Student implements Serializable { @Id // Bi-directional one-to-many relationship |
- In the Main.java, as samples, add at least 3 schools. Each district of corresponding school has at least 2 students.
- Exercise point: Criteria API
- In the Main.java, perform both JPQL and Criteria API as following. Metamodel class does not have to be used.
- Get all schools who have students whose grade is 3.0 or above
- In the Main.java, perform both JPQL and Criteria API as following. Metamodel class does not have to be used.
- Zip file of the the my_jpa2.0 NetBeans project. (Someone else should be able to open and run it as a NetBeans project.) You can use your favorite zip utility or you can use “jar” utility that comes with JDK as following.
- cd <parent directory that contains my_jpa2.0 directory> (assuming you named your project as my_jpa2.0)
- jar cvf my_jpa2.0.zip my_jpa2.0 (my_jpa2.0 should contain nbproject directory)
- Captured output screen – name it as homework_javaee6_jpa2.0.gif or homework_javaee6_jpa2.0.jpg (or homework_javaee6_jpa2.0.<whatever graphics format>)
- Any screen capture that shows that your program is working is good enough.