corner imagecorner image
FeaturesPluginsDocs & SupportCommunityPartners

Generating a JavaServer Faces CRUD Application from a Database

In this tutorial, you use the NetBeans IDE to generate and deploy a web application that displays data from a database. The tutorial demonstrates how to generate a web application with CRUD (Create, Read, Update, Delete) functionality that uses the Java Persistence API (JPA) to manage the database transaction. In the tutorial you first create entity classes based on tables in a database and then create JavaServer Faces (JSF) pages from the entity classes using the JSF Pages from Entity Classes wizard.

The JSF Pages from Entity Classes wizard enables you to quickly and easily generate JSF pages for working with a database based on the entity classes in your project. The wizard also gives you the option to enable Ajax functionality in the generated JSF pages. The code generated by the wizard has the following features:

The code is easy to maintain and customize Handles all relationship types, generated and non-generated IDs, and embedded IDs, including embedded ID fields that correspond to foreign key columns Embedded ID fields are shown as read-only where appropriate Includes required checks to prevent non-nullable column violations and orphan checks to prevent non-nullable column violations in related entities (by leveraging nullable or optional annotation elements in the entity classes) Includes checks to verify that the current entity is correct in order to prevent errors if a user deviates from the normal page flow (for example, when working in multiple browser tabs) Forgoes per-property code in certain files in case you later need to modify your database schema Fields can easily be removed from the generated JSPs to simplify customization Graceful handling of situations when a user attempts to operate on an entity that has been deleted by another user or attempts to create an entity that already exists Pages can be styled easily

In addition to generating JSF pages for you, the JSF Pages from Entity Classes wizard incorporates the functionality of the JPA Controller Classes from Entity Classes wizard. If you want to create JPA controller classes for entity classes but do not want JSF pages generated for you, you can use the JPA Controller Classes from Entity Classes wizard rather than the JSF Pages from Entity Classes wizard.

Note. This tutorial uses NetBeans IDE 6.5. If you are using NetBeans IDE 6.1, see Generating a JavaServer Faces CRUD Application from a Database in NetBeans IDE 6.1.

Contents

Content on this page applies to NetBeans IDE 6.5

To follow this tutorial, you need the following software and resources.

Software or Resource Version Required
NetBeans IDE 6.5 Java
Java Development Kit (JDK) Version 6 or version 5

Note. The GlassFish application server is included in the NetBeans download.

Creating the Database

This tutorial uses a consulting agency database called consult. The database is not included when you install the IDE so you need to first create the database to follow this tutorial.

The consult database was designed to demonstrate the scope of IDE support for handling a variety of database structures. The database is thus not intended as an example of recommended database design or best-practice. Instead, it attempts to incorporate many of the relevant features that are potentially found in a database design. For example, the consult database contains all possible relationship types, composite primary keys, and many different data types. See the tables below for a more detailed overview of the database structure.

Note. If you created a Java DB version of the consult database using an older script, you should run the derby_drop_consult_v1.sql script to drop the tables before creating the database again.

Note. This tutorial uses the JavaDB database server but you can also complete the tutorial using the MySQL database server. To create the database in MySQL, download and extract the mysql-consult.zip archive. The archive contains SQL scripts for creating and populating the consult database. For more information on configuring the IDE to work with MySQL, see the Connecting to a MySQL Database tutorial.

Download derby-consult.zip and extract the archive to your local system.

When you extract the archive you will see the SQL scripts for creating and populating the database. The archive also has scripts for dropping tables.

In the Services window, expand the Databases node, right-click the JavaDB node and choose Start Server. Right-click the Java DB node and choose Create Database. Type consult as the Database Name, User Name, and Password in the Create Java DB dialog. Click OK.
Create New Database dialog box

A new node appears under the Databases node (jdbc:derby://localhost:1527/consult [consult on CONSULT]).

Right-click the new node and choose Connect. Choose File > Open File from the main menu and navigate to the extracted file derby_create_consult_v2.sql. Click Open.

The file automatically opens in the the SQL editor.

Make sure that the consult database is selected in the Connection drop-down list in the SQL editor toolbar and click the Run SQL button.
screenshot of SQL editor

When you click Run SQL, the following output appears in the Output window.

screenshot of Output window

Note. If at any time you want to clear the database, you can drop the consult schema and tables by running the derby_drop_consult_v2.sql script included in the archive.

Viewing the Database Structure

To see the if the tables were created correctly, expand the Tables node under the database connection node. You can expand a table node to see the table columns, indexes and any foreign keys. You can right-click a column and choose Properties to view additional information about the column.

screenshot of Services window

Note. If you do not see any tables under the Tables node, right-click the Tables node and choose Refresh.

If you look at the structure of the consult database you can see that the database contains tables that have a variety of relationships and various field types. When creating entity classes from a database, the IDE automatically generates the appropriate code for the various field types.

diagram on consult database

The following table describes the tables found in the consult database.

Non-generated, composite primary key (whose fields do not constitute a foreign key)
Database Table Description Design Features
CLIENT A client of the consulting agency
CONSULTANT An employee of the consulting agency whom clients can hire on a contract basis Includes a resume field of type LONG VARCHAR
CONSULTANT_STATUS A consultant's status with the consulting agency (for example, Active and Inactive are possible statuses) Non-generated primary key of type CHAR
RECRUITER An employee of the consulting agency responsible for connecting clients and consultants  
PROJECT A project that a client staffs with consultants of the consulting agency Non-generated, composite primary key that includes two fields constituting a foreign key to the CLIENT table
BILLABLE A set of hours worked by a consultant on a project, for which the consulting agency bills the relevant client Includes an artifact field of type CLOB
ADDRESS A client's billing address  
PROJECT_CONSULTANT Join table indicating which consultants are currently assigned to which projects Cross-references PROJECT and CONSULTANT, the former having a composite primary key

The consult database includes a variety of relationships. When creating entity classes from a database, the IDE automatically generates the properties of the appropriate Java type based on the SQL type of the columns. The following table describes the entity relationships for the consult database. (The inverse relationships are not shown.)

Entity Related Entity Relationship Information Description
CLIENT RECRUITER nullable one-to-one with manual editing; nullable one-to-many if not edited CLIENT has many RECRUITERs and RECRUITER has zero or one CLIENT (if not manually edited)
CLIENT ADDRESS non-nullable one-to-one CLIENT has one ADDRESS and ADDRESS has zero or one CLIENT
CLIENT PROJECT non-nullable one-to-many; in a Project entity, the value of the client field is part of the Project's primary key CLIENT has many PROJECTs and PROJECT has one CLIENT
CONSULTANT PROJECT many-to-many CONSULTANT has many PROJECTs and PROJECT has many CONSULTANTs
CONSULTANT BILLABLE non-nullable one-to-many CONSULTANT has many BILLABLEs and BILLABLE has one CONSULTANT
CONSULTANT_STATUS CONSULTANT non-nullable one-to-many CONSULTANT_STATUS has many CONSULTANTs and CONSULTANT has one CONSULTANT_STATUS
CONSULTANT RECRUITER nullable one-to-many CONSULTANT has zero or one RECRUITER and RECRUITER has many CONSULTANTs
BILLABLE PROJECT non-nullable one-to-many BILLABLE has one PROJECT and PROJECT has many BILLABLEs

Now that the database is created, you can create the web application and use the Entity Classes from Database wizard to generate entity classes based on the database tables.

Creating the Web Application Project

In this exercise you create a web project and add the JavaServer Faces framework to the project. When you create the project, you will select JavaServer Faces in the Frameworks panel of the New Project wizard.

Choose File > New Project (Ctrl-Shift-N). Select Web Application from the Java Web category. Click Next. Type ConsultingAgency for the project name and set the project location. Deselect the Use Dedicated Folder option, if selected.
For this tutorial there is little reason to copy project libraries to a dedicated folder because you will not need to share libraries with other users.
Click Next.
Set the server to GlassFish and set the Java EE Version to Java EE 5. Click Next. Select the JavaServer Faces checkbox in the Frameworks panel. Click Finish.

Note. When selecting the framework, be sure to select the JavaServer Faces framework, NOT Visual Web JavaServer Faces.

When you click Finish, the IDE creates the web application project and opens welcomeJSF.jsp in the editor. You can close welcomeJSF.jsp because you will not need to edit this file.

Generating the Entity Classes from the Database

After you create the database and the database connection is registered with the IDE, you can use the Entity Classes from Database wizard to quickly generate entity classes based on the tables in the database. The IDE can generate entity classes for each table that you select, and can also generate any necessary entity classes for related tables.

In the Projects window, right-click the ConsultingAgency node, and choose New > Entity Classes from Database. Select New Data Source from the Data Source drop-down list to open the Create Data Source dialog. Type jdbc/consult as the JNDI Name and select jdbc:derby://localhost:1527/consult [consult on CONSULT] as the Database Connection. Click OK to close the dialog box and return to the wizard.
Create Datasource dialog box

The tables in the consult database appear in the Available Tables listbox.

Click Add All in the wizard. Click Next.
New Entities from Database wizard
Type jpa.entities as the Package. Make sure that the checkbox to generate named queries is selected. Click Create Persistence Unit to open the Create Persistence Unit dialog box. Click Create in the dialog box to create the persistence unit and return to the wizard.

Note. You can keep the default values for the persistence unit.

New Entities from Database wizard Click Next. Keep the default values in the Mapping Options page of the wizard. Click Finish.

You can use the Mapping Options page of the wizard if you want to further customize the annotations or collection type in the generated entities. For this tutorial the default values are sufficient.

When using the wizard to create entity classes from a database, the IDE examines the relationships between the tables. In the Projects window, if you expand the jpa.entities Source Package node you can see that the IDE generated an entity class for each table except for the PROJECT_CONSULTANT table. The IDE did not create an entity class for PROJECT_CONSULTANT because the table is a join table.

The IDE also generated two additional classes for the tables with composite primary keys: CLIENT and PROJECT. The primary key classes for these tables (ClientPK.java and ProjectPK.java) have PK appended to the name.

screenshot of Projects window

If you look at the generated code for the entity classes you can see that the wizard added @GeneratedValue annotations to the auto-generated ID fields and @Basic(optional = "false") annotations to some of the fields in the entity classes. Based on the @Basic(optional = "false") annotations, the JSF Pages from Entity Classes wizard can generate code that includes checks to prevent non-nullable column violations for those fields.

Editing the Entity Classes

If desired, you can now edit the generated entity classes. In this exercise you will modify the implementations of the toString method in the entity classes. In the Client and Recruiter classes you will also modify the annotations to change the relationship between clients and recruiters from one-to-many to one-to-one. Because a nullable one-to-many relationship already exists between recruiters and consultants, for demonstration purposes in this tutorial you will establish a nullable one-to-one relationship between clients and recruiters.

Note. This section of the tutorial is optional and you do not need to make any changes to the entity classes before you generate the JSF pages with the JSF Pages from Entity Classes wizard.

Editing Address.java

Open the Address entity class and make the following changes.

Modify the return statement of the toString method to return the full address:
return line1 + ", " + line2 + ", " + city + ", " + region + ", " + country + ", " + postalCode;

You can use the IDE's code completion to help you add the fields.

screenshot of code completion for fields Fix your imports, if necessary, and save your changes.

Editing Billable.java

Open the Billable entity class and make the following changes.

Modify the return statement of the toString method to return the description, consultant id and project:
public String toString() {
        return description + ", " + consultantId + ", " + project;

Fix your imports, if necessary, and save your changes.

Editing Client.java

Modify the @OneToMany annotation on the recruiterCollection field to make the relationship one-to-one and change the field from a Collection to Recruiter recruiter.
@OneToOne(mappedBy = "client")
private Recruiter recruiter;

Modify the getters and setters for Collection<Recruiter> recruiterCollection according to the changes in the name of the field. The new getter and setter will look like the following:
public Recruiter getRecruiter() {
    return recruiter;
}

public void setRecruiter(Recruiter recruiter) {
    this.recruiter = recruiter;
}

It might be simpler to delete the getter and setter for Collection<Recruiter> recruiterCollection and then generate a new getter and setter for Recruiter recruiter using the Insert Code dialog. To create a new getter and setter, right-click in the source code and choose Insert Code (Alt-Insert) and then select Getter and Setter. Select recruiter in the Generate Getter and Setter dialog box and click Generate.

Generate Getters and Setters dialog box Modify the return statement of the toString method to return String.valueOf(clientPK).
public String toString() {
    return String.valueOf(clientPK);
}

Fix your imports, if necessary, and save your changes.

Editing ClientPK.java

Modify the return statement of the toString method to return the client name and department number.
public String toString() {
    return clientName + ", " + "Dept. " + clientDepartmentNumber;
}

Fix your imports, if necessary, and save your changes.

Editing Consultant.java

Modify the return statement of the toString method to return the email.
public String toString() {
    return email;
}

Fix your imports, if necessary, and save your changes.

Editing ConsultantStatus.java

Modify the return statement of the toString method to return the status ID and description.
public String toString() {
    return statusId + ", " + description;
}

Fix your imports, if necessary, and save your changes.

Editing Project

Modify the return statement of the toString method to return the following:
public String toString() {
    return (projectPK == null ? "(unnamed project)" : projectPK.getProjectName()) + ", " + client;
}

Fix your imports, if necessary, and save your changes.

Editing Recruiter.java

Modify the @ManyToOne annotation on the client field to mark the relationship as one-to-one.
@OneToOne
private Client client;

Modify the return statement of the toString method to return the email.
public String toString() {
    return email;
}

Fix your imports, if necessary, and save your changes.

Generating JSF Pages From Entity Classes

Now that the entity classes are created, you can create the web interface for displaying and modifying the data. You will use the JSF Pages from Entity Classes wizard to generate JavaServer Faces pages. The code generated by the wizard includes checks based on the annotations in the entity classes. The wizard also gives you the option to enable Ajax functionality in the application by extending the JavaServer Faces technology with Dynamic Faces technology.

For each entity class the wizard generates the following:

a JPA controller class a JSF controller class a JSF converter class a directory containing four JSP files (Detail.jsp, Edit.jsp, List.jsp, New.jsp) managed bean elements, converter elements and navigation rules for the entity in faces-config.xml

The wizard also generates the following classes used by the controller classes:

exception classes used by the JPA controllers utility classes used by the JSF controllers

To generate the JSF pages:

Right-click the project node in the Projects window and choose New > JSF Pages from Entity Classes to open the New JSF Pages from Entity Classes wizard.

The Available Entity Classes box lists the seven entity classes in the project. The box does not list the embeddable classes (ClientPK.java and ProjectPK.java).

Click Add All to move all the classes to the Selected Entity Classes box. Click Next.
New JSF Pages from Entity Classes wizard
Type jpa.controllers for the JPA Controller Package. Type jsf for the JSF Classes Package. Select Ajax-enable generated pages. Click Finish.

When you click Finish, the IDE creates the JPA controller classes in the jpa.controllers package and the JSF converter and JSF controller classes in the jsf package. Each JPA controller class handles the operations for the corresponding entity class, including creating, editing, and destroying instances of the entity class via the Java Persistence API. Each JSF converter class implements the javax.faces.convert.Converter interface defined by JavaServer Faces and performs the work of converting instances of the corresponding entity class to String objects and vice versa. Each JSF controller class is specific to the corresponding generated JSP and includes code that invokes methods in the appropriate JPA controller class and demonstrates which exceptions to catch.

Note. In general, when modifying your application you will want to modify the controller logic in the JSF controller classes and use the generated code as an example.

If you expand the Web Pages node, you can see that the IDE generated a folder for each of the entity classes. Each folder contains the files Detail.jsp, Edit.jsp, List.jsp and New.jsp. The IDE also modified welcomeJSF.jsp by inserting links to each of the List.jsp pages.

screenshot of Web Pages directory in Projects window

If you expand the Source Packages node you can see the controller, converter, exception, and utility classes that the wizard generated.

screenshot of Source Packages directory in Projects window

If you expand the Configuration Files node and open faces-config.xml in the XML editor, you can see that the IDE inserted the managed-bean and converter elements for each of the controller and converter classes. The IDE also inserted a navigation-rule element for each JSP, indicating the logical outcome that causes the application to navigate to that JSP.

Enabling Ajax in the Application

The final pane of the JSF Pages from Entity Classes wizard gives you the option to select Ajax-enable generated pages to enable Ajax functionality in the application through the Dynamic Faces extension to the JSF framework. The wizard adds the required JSF Extensions libraries to the project and configures the application's deployment descriptor to enable the Ajax lifecycle. For more about Dynamic Faces JSF Extensions see the JavaServer Faces Technology Extensions site.

New JSF Pages from Entity Classes wizard

If you select the option the wizard performs the following actions.

Adds JSF Extensions libraries to the project (jsf-extensions-common, jsf-extensions-dynamic-faces, commons-logging, and shale-remoting) that are required for using Dynamic Faces technology in the project.
screenshot of Libraries node in Projects window
Modifies web.xml to configure FacesServlet to use the Ajax lifecycle by adding an entry for the javax.faces.LIFECYCLE_ID initialization parameter and setting the value to com.sun.faces.lifecycle.PARTIAL.
screenshot of web.xml editor
Generates the JSP fragment file AjaxScripts.jspf in the WEB-INF/jspf directory. AjaxScripts.jspf renders script tags for JavaScript files contained in the Dynamic Faces libraries.

The application contains a JavaScript file jsfcrud.js in the Web Pages directory. The jsfcrud.js file checks if Dynamic Faces is enabled by checking if the script tags for the Dynamic Faces JavaScript files were rendered. If Dynamic Faces is enabled then the form is configured to send Ajax requests.

After enabling Ajax in the application with Dynamic Faces extensions, you can modify the application to add further functionality provided by Dynamic Faces extensions.

Note. If you want to disable Ajax in the application later, you can comment out the contents of AjaxScripts.jspf by adding <%-- to the beginning of the file and --%> to the end of the file.

Generating JPA Controller Classes From Entity Classes

In the generated web application the JPA controller methods are accessed by methods in the JSF controller class. When you use the JSF Pages from Entity Classes wizard the IDE automatically generates JPA controller classes for each of the selected entities. But the use of JPA controller classes is not restricted to JSF web applications. You can use JPA controller classes in other applications that use the Java Persistence API (for example, in desktop applications) to work with entity classes and manage entity persistence.

The JPA Controller Classes from Entity Classes wizard enables you to easily create JPA controller classes in projects. To create JPA controller classes, open the New File wizard and choose JPA Controller Classes from Entity Classes in the Persistence category. In the wizard you specify the entity classes for which you want the JPA controller classes and then specify where you want the IDE to create the files. The wizard also automatically creates exception classes used by the JPA controller classes.

screenshot of JPA Controller Classes wizard

If you update your database schema you can run the Entity Classes from Database and JPA Controllers from Entity Classes wizards again to regenerate the classes. If desired, after you create the JPA controller classes, you can run the JSF Pages from Entity Classes wizard and specify the package of the existing JPA controller classes, in which case the existing JPA controller classes will be leveraged rather than regenerated.

Adding Data to the Database

Now that you have finished creating the application, you can deploy and run the application. The Consulting Agency database you created is unpopulated. You need to add data to the database either by adding data through the web interface or by running an SQL script. After you add the data you will see how the relationships between the tables function.

Adding Data With an SQL Script

If you do not want to add the data through the web forms, you can run the derby_insert_data_consult_v2.sql script included in the derby-consult.zip archive.

Open derby_insert_data_consult_v2.sql by choosing File > Open File from the main menu.

The file automatically opens in the the SQL editor.

Note. If you are using the MySQL database server, open the mysql_insert_data_consult_v2.sql file included in the mysql-consult.zip archive.

Make sure that the consult database is selected in the Connection drop-down list in the SQL editor toolbar and click the Run SQL button in the toolbar.
screenshot of SQL editor and insert data script

You can see the result of the script execution in the Output window.

Adding Data With the Web Interface

You can add data to the database by launching the application in your browser and then adding data through the web forms.

Click Run Main Project in the main toolbar.

The IDE saves all changed files, rebuilds the application, and deploys the application to the server. Your default web browser opens to the local address http://localhost:8080/ConsultingAgency/.

screenshot of browser window with welcomeJSF page Click Show All Address Items and click New Address. Add the following data in the New Address form.
Field Value
Line1 100 Data Street
Line2 Suite 432
City San Francisco
Region California
Country USA
PostalCode 94103
Click Create. Click Index to return to the index page. Click Show All Client Items and click New Client. Add the following data in the New Client form.
Field Value
ClientDepartmentNumber 2000
ClientName Big Data Corp.
ContactEmail
ContactPassword accounting
BillingAddress 100 Data Street
Click Create and then Index to return to the index page. Click Show All Project Items and click New Project. Add the following data in the New Project form.
Field Value
ProjectName Secret Project
ContactEmail
ContactPassword project.manager
Click Create and then Index to return to the index page. Click Show All ConsultantStatus Items and then click New ConsultantStatus. Add the following data in the New ConsultantStatus form.
Field Value
StatusId A
Description Active
Click Create and then Index to return to the index page. Click Show All Consultant Items and then click New Consultant. Add the following data in the New Consultant form.
Field Value
Email
Password janet.smart
HourlyRate 80
BillableHourlyRate 120
ProjectCollection Secret Project
StatusId A, Active

Note. Make sure you select Secret Project in the list box for ProjectCollection.

Click Create and then Index to return to the index page. Click Show All Billable Items and then click New Billable. Add the following data in the New Billable form.
Field Value
StartDate 2008-10-13 00:00:00.0
EndDate 2008-10-17 00:00:00.0
Hours 40
HourlyRate 80
BillableHourlyRate 120
Description begin gathering requirements
ConsultantId
Project Secret Project
Click Create and then click New Billable. Add the following data in the New Billable form.

This time you will type finish gathering requirements in the Description field.

Field Value
StartDate 2008-10-20 00:00:00.0
EndDate 2008-10-24 00:00:00.0
Hours 40
HourlyRate 80
BillableHourlyRate 120
Description finish gathering requirements
ConsultantId
Project Secret Project
Click Create and return to the index page. Click Show All Recruiter Items and click New Recruiter. Add the following data in the New Recruiter form.
Field Value
Email
Password bob
ConsultantCollection

Note. Make sure you select

in the list box for ConsultantCollection. Leave the Client drop down list empty. Click Create and then Index to return to the index page.

After adding data to the database you can navigate through the generated pages to see the relationships between the tables.

Exploring Functionality in the Generated Code

After you populate the database you can see examples of how the code generated by the wizard is based on the properties of the database fields.

Read-only Primary Key Fields

If a field in the database is a primary key, the wizard generates code to prevent the user from editing the field in the generated forms. The following examples illustrate instances where the primary key field is read-only.

If you navigate to the New Client page you can see that the ProjectCollection field is read-only. If the application permitted an attempt to change the Client associated with an existing Project, the operation would fail because the Client associated with a Project is part of the Project's primary key. You can verify this in the SQL script by examining the project_pk primary key and the project_fk_client foreign key. If you navigate to the Editing Project Page you can see that the Client field is read-only. Again, the field is read-only because the Client associated with a Project is part of the Project's primary key.

Generated Error Checks

The generated code can check if a user action would result in an error. For example, if a table has a column that cannot be null, the code can check if an action would result in a non-null violation for the column and instead display an error message. After you populate the database you can see examples of the generated checks by trying to edit the data in the forms. You will receive an error message if you attempt to do the following actions.

Create another Project item, again specifying Secret Project as the ProjectName, and completing the ContactEmail and Client fields.

An error message appears indicating that the item already exists.

Create another Address item, but leave all the fields blank.

Error messages appear indicating the required fields.

Edit the " " Consultant item by deselecting "finish gathering requirements" in the BillableCollection list.

An error message appears indicating that the Billable item that you deselected must be retained because its consultantId field cannot be null.

Destroy the "Secret Project, Big Data Corp., Dept. 2000" Project item.

An error message appears indicating that the Project item cannot be destroyed because the Project item's associated Billable items have a project field that cannot be null.

Destroy an item that has already been destroyed by another user.

An error message appears indicating that the item no longer exists, and the List.jsp page subsequently does not display the item.

Note. You can do this if you use two different browsers (e.g., Firefox and Internet Explorer) and navigate to the same page (e.g., the Listing Billable Items page) in each browser. Destroy one of the Billable items in one of the browsers and then try to destroy the same item in the other browser.


See Also

For more information about using NetBeans IDE to develop web applications using Java Persistence and JavaServer Faces, see the following resources:

Companion
Projects:
MySQL Database Server   GlassFish Community: an Open Source Application Server   Open Solaris  Open JDK: an Open SourceJDK   Mobile & Embedded Community     Sponsored by 
Sponsored by Sun Microsystems


You are viewing a mobilized version of this site...
View original page here

How do you rate mobile version of this page?

Mobilized by Mowser Mowser