Products Docs & Support Community

Using Java Persistence API in a Visual Web Application

August [Revision number: V6.0]    

Using NetBeans IDE 6.0 and the Visual Web tools, you can write applications that connect to database tables using the Java Persistence API (JPA) in addition to the Visual Web data provider components. After you establish the connection to the database table, you can use the Java Persistence API to perform database CRUD operations (that is, create, read, update, and delete operations). The ability to use the Java Persistence API gives you greater flexibility when developing database-dependent applications.

This article (the first of two) takes you through the set-up steps for using the Java Persistence API from a Visual Web application. You will learn how to use the API to connect or bind to a database table, which gives you access to the data in the table. In the second article, you will see how to use the API to add, update, and delete database table rows. In addition, the article includes tips for getting the most from the NetBeans IDE and its visual web functions.

Contents

Overview
Why Use the Java Persistence API
Creating a Database Table
  Linking Two Projects
  Binding to a Database Table
  Setting Key Attributes With JPA
  Creating the Classes
  Binding the Entity Bean to the Table Component
  Summary
 

This article works with the following technologies and resources.

JavaServer Faces Components/
Java EE Platform
not required1.2 with Java EE 5*
Travel Database not requiredNot required
BluePrints AJAX Component Library not requiredNot required

* To take advantage of NetBeans IDE 6.0's Java EE 5 capabilities, use an application server that is fully compliant with the Java EE 5 specification such as the Sun Java Application Server 9/GlassFish.

This article has been tailored for use with the Sun Java Application Server PE 9.0 Update Release 1 and with Tomcat 5.5.17. If you are using a different server, consult the Release Notes and FAQs for known problems and workarounds. For detailed information about the supported servers and Java EE platform, see the Release Notes.

Overview

This article, the first in the series, starts by showing you how to directly bind a NetBeans IDE Visual Web Table Component to an array or list of Objects (also referred to as POJOs or Plain Old Java Objects). If you are familiar with accessing database tables with the Visual Web tools, you have used the data provider components. You may have dropped a Table component from the Palette onto a page and then dropped a database table onto that Table component. When you dropped the database table onto the page, the Visual Web tools created a data provider component for you, and this data provider handled the database table binding and data access.

Now you are going to bind the same Visual Web Table component to a database table without the data provider support; instead, you do the binding using the Java Persistence API. Using JPA, you can obtain the database table data as a list or array of entity beans (POJOs) and directly bind that array to a Visual Web table component without the intermediate step of using an ObjectListDataProvider or ObjectArrayDataProvider. You can then use the Visual Web table component features to manipulate the data.

In addition to covering using Java Persistence API, we also showcase some of the features of the NetBeans IDE. You'll see how to use the IDE to:

  • Create database tables, columns, and keys
  • Link a Visual Web project to a standard Java SE project so that the web project can use classes in the Java SE project
  • Define a persistence unit, required when using Java Persistence in an application
  • Generate entity classes from database tables
  • Use the Java source editor functions, particularly to generate code, fix missing import statements, and reformat code
  • Bind properties to data

Subsequent articles will showcase using specific Visual Web components, such as the Grid Panel component to control page layout.

Why Use the Java Persistence API

The Java Persistence API, introduced in the Java EE 5 platform, can be used directly by web applications and clients, both within and outside of the Java EE platform. If you choose, you can have your application talk directly to the underlying database using JPA and bypassing the Visual Web data provider components.

There are a number of reasons why you might want to use the Java Persistence API. For one, it is a simple, lightweight programming model since it treats entity objects (that is, Enterprise JavaBean components that use container-managed persistence) as plain old Java objects (POJOs).

Treating entity objects as POJOs leads to other advantages to using the Java Persistence API. Because entities are POJOs, an entity class can extend another entity class or a nonentity class, plus a nonentity class can extend entity classes as well. As POJOs, entity objects can be serialized and sent across the network to other address spaces and also used in a persistence-unaware environment. As a result, you don't have to use any special data transfer objects to send entities to remote locations.

With the Java Persistence API, you use a standard application programmer interface to perform typical database operations (the Create/Read/Update/Delete, or CRUD operations) that involve entities. Application portability is also improved. Because it is easier for third-party persistence providers to develop and provide plug-ins to their database systems, you can combine different Java EE containers with different database systems and without compromising application portability.

In addition, you can use the native query language of the underlying database to form queries. Furthermore, the packaging rules for entities that use the Java Persistence API are also simplified. Using JPA might be better for you if your application has high transactional throughput requirements because it supports optimistic locking--that is, it avoids locks for the sake of performance-- although as a result some transactions may fail due to collisions with other users.

To find out more about the Java Persistence API, see the article "The Java Persistence API - A Simpler Programming Model for Entity Persistence" .

For an in-depth guide to the Java Persistence API, see the article "Using the Persistence API in Desktop Applications".

Creating a Database Table

The step-by-step instructions that follow assume that you have set up a database called sample that includes a database table called Users. The Users table should have four columns, as follows:

  • user_id - Primary key; Type: INTEGER
  • userName - Type: String
  • password - Type: String
  • email_address - Type: String

Executing SQL Statements

You can add a Users table to the sample Derby database included for Visual Web applications. You can execute an SQL script from a file to create this table. Or, you could execute each line of SQL code individually. The context menu functions for the database table nodes in the Services pane (formerly called the Runtime pane) include functions to create new tables and execute SQL code.

Figure 1: SQL Execute Command

 

The Execute Command function opens an Editor window to which you can enter one or more lines of SQL code. Execute the contents of the window by clicking the Run button. Be sure that the Connection field indicates you are connected to the sample database.

Figure 2: SQL to Create Users Table

Defining Primary Key Values

You can use the following code to create the Users table in the Derby sample database. Note that the clause GENERATED ALWAYS AS IDENTITY indicates that the user_id primary key value will be generated and automatically incremented by the Derby DBMS when it adds a new record. If you manually add records to this table, such as with the INSERT INTO code, be sure to use the reserved word DEFAULT to indicate that the value of user_id is supplied by the database.

Code Sample 1: SQL to Create Users Table
create table "APP"."USERS" (
    userName VARCHAR(50), password VARCHAR(12), email_address VARCHAR (50),
           user_id INTEGER GENERATED always AS IDENTITY);
alter table Users add constraint usersPK PRIMARY KEY (user_id);
INSERT INTO Users VALUES ('Joe', 'joepw', '...',DEFAULT);

There are other ways to define the primary key value with Derby. In addition to the Derby Reference Manual, which you can find from the Apache Derby site, you should refer to Brian Leonard's blog on the subject.

Keep in mind, however, that different database management systems handle primary key values differently. For example, with MySQL, the table definition for generating and auto incrementing the primary key is:

`user_id` int(10) unsigned NOT NULL auto_increment, ...

Later, you will generate an entity class from this database table definition. The generated entity class is the Java Persistence representation of the database table. Since TopLink is the reference implementation for JPA, you can refer to the TopLink documentation for more information on id generation. With Derby, you will have to manually add an annotation to the generated class to indicate the generated value strategy (@GeneratedValue) for the primary key. With MySQL, you do not need to specify a generated value strategy in this entity class.

Using the IDE GUI to Create a Table

If you prefer, use the IDE's Create Table function to create the table and define the columns. The Create Table dialog is fairly self explanatory. Enter the table name in the Table name field. Click the Add Column button to add columns. Check the key column to define the primary key--the dialog automatically checks Index and Unique. For each column you add to the table, be sure to choose the data type from the Data type drop down list and set its size.

Figure 3: Using the Create Table Window (click image to enlarge)

 

Linking a Visual Web Project to a Java Standard Edition Project

To use the Java Persistence API from a Visual Web application, you actually create two projects. One project is your Visual Web project. The other is a Java Standard Edition (SE) application project that includes several classes whose code the web application will call. From within this Java SE application project, you generate a persistence unit to get a handle to the Java Persistence API. Your web application then uses the classes created in the Java SE application project to establish the database binding, and later to do the database update, delete, and add operations.

 

Creating the Projects

  1. Create the Java SE application project. Begin by creating the Java SE application project, which is a general Java project. Click the New Project icon in the toolbar, then select General in the Categories column and Java Application in the Projects column. Then click Next.
  2. Figure 4: Create Java Application (click to enlarge image)
  3. In the New Java Application screen, set the project name to TestModelApp. You also need to set the package to com.samples.model. Change the default Create Main Class entry from textmodelapp.Main to com.samples.model.Main.
  4. Figure 5: Set the Project and Package Names (click to enlarge image)
  5. Create the Visual Web project. Next, you create the Visual Web project. From the New Project dialog, select Web as the category and Web Application as the project, then click Next.
    Figure 6: Create the Web Project (click to enlarge image)
  6. In the New Web Application dialog, set the project name to TestWebApp. The project location should default to the same location as the TestModelApp project. Click Next to go to the third screen, where you select the framework.
    Figure 7: Set the Web Project Name and Location (click to enlarge image)
  7. Select Visual Web JavaServer Faces for the framework. When you make this selection, the screen displays configuration settings. Change the Default Java Package setting from testwebapp to com.samples.web. After completing this step, TestModelApp and TestWebApp appear as nodes in the Project window.
    Figure 8: Set the Web Application Framework and Package

Linking the Projects Together

Now you want to link the two projects together. Specifically, you want the TestModelApp project to be a dependent project to the TestWebApp project. To make TestModelApp a dependent project of TestWebApp, you need to add the TestModelApp.jar file to the TestWebApp project. Here's how to do this:

  1. In the Projects window, right Click the TestWebApp project node and select Properties from its context menu.
  2. In the Project Properties dialog, click the Libraries node in the Categories section on the left. Then, click Add Project.
    Figure 9: Add Compile-Time Libraries (click to enlarge image)
  3. In the Add Project window, browse to the location with the TestModelApp project and select it. Then click Add Project JAR Files. This step adds the TestModelApp jar file to the compile-time libraries for the TestWebApp project, and TestModelApp appears in the Project Properties screen. Click OK in the Project Properties screen to complete the process.
    Figure 10: Add the JAR File (click to enlarge image)

Binding to a Database Table

You use the Java Persistence API to bind a table that is displayed in the application to a database table. After you do this binding, you use the API to retrieve rows from the database table, but you display the data using the Visual Web Table component's built-in display features.

Connecting to the Database

To begin, you connect to the database with the Users table from within the TestWebApp project. If you are using the sample Derby database and have not yet connected to it, open the Services window, expand the Databases node, open the context menu for the jdbc:derby://localhost:1527/sample [app on APP] node and choose Connect. If you are using a different DBMS, then, if needed, set up a driver for that database and create a new connection, providing the necessary connection parameters. (If you keep the database name as sample it will be easier to follow the rest of this walk-through.)

If you have not yet created the Users table, now is the time to do so. See Creating a Database Table.

From the Services pane, verify that the connection to the database is established. Open the Databases-><sample database>->Tables node and verify that the Users table is correct.

Creating a Java Persistence Entity Class Representing the Users Database Table

Create an entity class representing the Users table. As noted previously, the entity class is the Java Persistence representation of the database table definition. Each entity class contains a set of annotations (identified by a leading @ sign) that define the table's relationships and keys. Create the entity class from within the TestModelApp project using the Entity Classes from Database function.

  1. In the Projects (or Files) window, right click the TestModelApp project. From the context menu, select New -> Entity Classes from Database.
  2. The New Entity Classes from Database Database Tables dialog displays. If the Database Connection field is blank, then select the sample database from the pull-down list. The Available Tables column displays all the tables in the sample database, including the Users table. Select the USERS table and click Add to move Users to the Selected Tables column. Click Next after moving the Users table.
    Figure 11: Select the Database Table for the Entity Class (click image to enlarge)
  3. The Entity Classes dialog displays. The IDE displays the database table name Users, and suggests a class name of Users. (Double click this class name to change it, if you want.) The dialog also indicates that the package is com.samples.model. Click Create Persistence Unit.
    Figure 12: Create the Persistence Unit (click image to enlarge)

Creating a Persistence Unit

  1. In the Create Persistence Unit dialog, set the Persistence Unit Name to samplePU. Leave the other fields with the default values. Click Create, then click Finish in the Entity Classes screen to complete the operation and create the samplePU persistence unit.
  2. Figure 13: Name the Persistence Unit
  3. It is a good idea to verify that the persistence unit is created correctly. To do so, expand the TestModelApp Source Packages->META-INF node and double click the persistence.xml file. The Design window displays information about the persistence unit, while the Navigator window shows the XML properties.
    Figure 14: Verify Persistence Unit (click image to enlarge)
  4. Click the XML tab to see the complete XML listing. The properties in the file should correctly reflect the database name, its url, driver, and password, along with the package and class name (com.samples.model.Users). The transaction type is RESOURCE_LOCAL and the provider is oracle.toplink.essentials.PersistenceProvider. Important: Be sure that the password field is filled in correctly.
    Figure 15: Persistence Unit XML Definitions (click image to enlarge)

Setting Key Attributes With Java Persistence Annotations

If you are working with the Derby database, you need to make some modifications to the generated Users.java code to handle auto generation of the primary key value. However, other database systems may handle primary key value generation differently, and any modifications you make to the generated Users.java class must match the underlying database's primary key generation policies.

Notice that the listing includes code lines that begin with an @ sign followed by some text, such as @Id or @Column(name = "PASSWORD"). The @ sign marks those lines that are Java Persistence annotations.

@Id and @GeneratedValue Annotations

After you create the Users.java entity class, you need to modify the class so that the primary key field (the user id field) is automatically generated by the database. JPA identifies the primary key with the @Id annotation. You add a second annotation to the primary key that indicates the strategy for generating the primary key value: @GeneratedValue(strategy=GenerationType.<...>), where the strategy clause is optional. Note that the generation strategy you choose must correlate with the capabilities of your database.

Generated Type Strategies

There are four generation type strategies, as follows:

  • GenerationType.AUTO - With this strategy, the persistence provider (in our example, the persistence provider is Oracle TopLink) selects the key generation strategy. If you specify the annotation as simply @GeneratedValue, with no strategy clause, then the generation type defaults to AUTO.
  • GenerationType.TABLE - With this strategy, the persistence provider uses a database table to manage primary keys.
  • GenerationType.SEQUENCE - This strategy works only with databases that support Sequences, because the persistence provider uses a database sequence for key generation.
  • GenerationType.IDENTITY - This strategy requires the database to support the IDENTITY column type, because the persistence provider lets the database generate the key.

Generating Primary Key Value With Derby Database

Since the Derby database supports the IDENTITY column type and thus can generate a unique value for the primary key, we pass that responsibility to the database. Thus, add the following line of code to the primary key definition: @GeneratedValue(strategy = GenerationType.IDENTITY).

The Users.java code defining the table should look as follows after you make your modifications:

Code Sample 1: Modified Users.java Class
public class Users implements Serializable {
  @Column(name = "USERNAME")
  private String username;
  @Column(name = "PASSWORD")
  private String password;
  @Column(name = "EMAIL_ADDRESS")
  private String emailAddress;
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "USER_ID", nullable = false)
  private Integer userId;
  ...

Using the Fix Imports Function

Note that the @GeneratedValue tag requires two classes: javax.persistence.GeneratedValue and javax.persistence.GenerationType. Use the Fix Imports function to import these classes. Right click anywhere in the source editor window and select Fix Imports from the pop-up menu. The Fix Imports function adds these two import statements to the class:

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

As noted above, other databases may require a different modification to the Users.java code, or no modification at all. For example, with a MySQL database, you do not need to include the @GeneratedValue annotation since the database automatically generates the primary key value if you specify auto_increment for the user_id column when you create the table definition.

Creating the Classes

Creating the Entity Controller Class

You continue to work in the TestModelApp project, creating a new class called UserController in the com.samples.model package. (We provide the code for this class below, and you can paste it into your class.)

Expand the TestModelApp->Source Packages->com.samples.model node. Notice that there are already two classes in the package: Main.java and Users.java. Right click the com.samples.model node and select New->Java Class. In the New Java Class dialog, set the class name to UserController (leave the location as Source Packages and the package name as com.samples.model).

Figure 16: Create the UserController Class (click image to enlarge)

You should see the skeleton source code for this new class in the Edit window. Add the following code to the class:

Code Sample 2: UserController Code
 private EntityManagerFactory emf;
 private EntityManager getEntityManager() {
 if(emf == null){
    emf = Persistence.createEntityManagerFactory("samplePU");
 }
    return emf.createEntityManager();
 }
 public Users[] getUsers() {
    EntityManager em = getEntityManager();
    try{
        javax.persistence.Query q = em.createQuery("select c from Users as c");
        return (Users[]) q.getResultList().toArray(new Users[0]);
    } finally {
        em.close();
    }
 }

Use the Fix Imports function to import the required classes. (Right click in the source editor window and select Fix Imports from the pop-up menu.) Doing so adds the following three import statements to the class:

import javax.persistence.EntityManager;

import javax.persistence.EntityManagerFactory;

import javax.persistence.Persistence;

You can use the Reformat Code function, available from the same pop-up menu, to format the code alignment.

Notice that the UserController class includes the method getUsers, which invokes the createQuery method on the javax.persistence.EntityManager interface to create a query that returns the rows of data from the Users table. The results of the query are returned as an array.

Binding the Entity Bean to the Table Component

You are ready to bind the entity component for accessing the Users database table to a Table component in the TestWebApp project. (Recall that you created the entity bean in the TestModelApp.) You do this binding from within the TestWebApp project.

Here are the binding steps:

  • Create a property in SessionBean1 that returns an array of Users objects.
  • Create a method to initialize the array.
  • Then, bind the array of Users objects to the Table component.
  • Use the Java Persistence API Entity Manager to invoke the Users array initialization method.

Let's examine these steps in more detail.

Creating a Property in the Session Bean

  1. First, create a property in SessionBean1 that returns an array of Users objects. In the Outline window, double click on SessionBean1 to open it in the Java Source Editor. Or, double click SessionBean1 from within the Projects window TestWebApp->Source Packages->com.samples.web node. If you do not see the Outline window, try displaying a page from TestWebApp, such as Page1, in the Design window. The Outline window should display beneath the Navigator window. If you still do not see the Outline window, click the Design tab in the Design window.
  2. Add a property called users to SessionBean1. Type in the following line of code: private Users[] users;
  3. Fix any errors. Most likely, the line you just entered will be marked as an error. If so, use the source editor's context menu Fix Imports function to fix this error. (Be sure to correct this error before continuing to the next step.) To fix the error, the IDE adds the following import statement: import com.samples.model.Users;
  4. Generate get and set methods for the users property. Right click the line of code you typed in and select the action Generate Code. Choose Getter and Setter from the popup menu. Then, select users: Users[].
    Figure 17: Add users Property to SessionBean1 (click image to enlarge)

The Generate Code action adds public get and set methods. When finished, SessionBean1 should include the following code.

Code Sample 3: Get and Set Methods for users Property
 private Users[] users;
    public Users[] getUsers() {
    return users;
 }
    public void setUsers(Users[] users) {
    this.users = users;
 }

Creating the Initialization Method

  1. Add a method called updateUsers to SessionBean1. This method will be used to initialize the users property. Here's the code for the method:
    Code Sample 4: updateUsers Method
    public void updateUsers(){
         UserController usersController = new UserController();
         users = usersController.getUsers();
    } 
  2. Use the Fix Imports function to fix the import needed for updateUsers. If there are errors in the code, do a Save All files to clear them.
  3. Add a call to the updateUsers method in the SessionBean1 init method: updateUsers();. The SessionBean1 init method should look as follows (comment lines not shown):
    Code Sample 5: SessionBean1 init Method
    public void init(){
         super.init();
         try {
              _init();
         } catch (Exception e) {
              log("SessionBean1 Initialization Failure", e);
              throw e instanceof FacesException ? (FacesException) e: new FacesException(e);
         }
         updateUsers();
    } 
  4. Save all the files.
  5. Build both the TestModelApp and TestWebApp projects.

Binding the Property to the Table Component

Now you are ready to bind the users property you just added to a Table component.

  1. From TestWebApp->Web Pages, double click Page1.jsp to open the page in the Design window.
  2. Drag a Table component from the Palette and drop it on the page in the Design window. It should as follows:
    Figure 18: Add the Table Component to Page1
  3. Right click the Table component on the page and click Bind to Data from its context menu. In the Get Data From drop down list, select users (from SessionBean1) as the binding array. (Note that if you do not see the users property displayed in the drop down list, right click in the Design window and click the Refresh option in the context menu. Or simply click the Refresh button in the toolbar. If you still do not see the users property displayed in the drop down list, then close and reopen the TestWebApp project.)
    Figure 19: Select users in Bind to Data Dialog
  4. The Table component display in the Design window should change to the following. If needed, adjust the columns to be displayed.
    Figure 20: Table Component Bound to users Array in Design Window
  5. Deploy and run the TestWebApp project. The Table component displays, and, if you created sample data for the database table, that data should displays as shown here:
    Figure 21: Table Component on Page1 in Browser

Summary

This article walked you through the necessary steps to use the Java Persistence API from a Visual Web application. It showed you how to set up and link together a Java SE project and a Visual Web project. It also showed you how to create the database table and required keys and use the Java Persistence API to bind to the database. The article supplied the custom Java code needed to access the database table, and it demonstrated how to create an entity bean to hold the table data. Finally, it showed you how to bind the entity bean to a Visual Web Table component, and the Table component simplifies displaying the database table data.

See Also:


This page was last modified:  August 7,