blob: 364f57a10062779c3c3af21d06a4dbe9eb9d51b4 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="description" content="Demonstrates how the IDE can generate robust and easily maintainable code when generating JSF pages from entity classes.">
<meta name="keywords" content="NetBeans, IDE, integrated development environment,
Java, Java EE, open source, web technology, CRUD, JSF, tutorial, database">
<link rel="stylesheet" type="text/css" href="../../../netbeans.css">
<link rel="stylesheet" type="text/css" href="../../../lytebox.css" media="screen">
<script type="text/javascript" src="../../../images_www/js/lytebox-compressed.js"></script>
<script src="../../../images_www/js/listCollapse.js" type="text/javascript"></script>
<title>Generating a JavaServer Faces 2.x CRUD Application from a Database - NetBeans IDE Tutorial</title>
</head>
<body>
<!-- Copyright (c) 2009, 2010, 2011, Oracle and/or its affiliates. All rights reserved. -->
<h1>Generating a JavaServer Faces 2.x CRUD Application from a Database</h1>
<p>In this tutorial, you will use the NetBeans IDE to create a web application that interacts
with a back-end database. The application provides you with the ability to view and
modify data contained in the database - otherwise referred to as <em>CRUD</em> (Create,
Read, Update, Delete) functionality. The application that you will develop relies on the following technologies.</p>
<ul>
<li><strong>JavaServer Faces (JSF) 2.x</strong> for front-end web pages, validation handling,
and management of the request-response cycle.</li>
<li><strong>Java Persistence API (JPA) 2.0</strong> using EclipseLink to generate entity
classes from the database, and manage transactions. (EclipseLink is the reference
implementation for JPA, and is the default persistence provider for the GlassFish server.)</li>
<li><strong>Enterprise JavaBeans (EJB) 3.1</strong>, which provides you with stateless EJBs
that access the entity classes, and contain the business logic for the application.</li>
</ul>
<p>The IDE provides two wizards which generate all of the code for the application. The first
is the <a href="#generateEntity">Entity Classes from Database wizard</a> which enables you
to generate entity classes from the provided database. After you create entity classes, you
use the <a href="#jsfPagesEntityClasses">JSF Pages from Entity Classes wizard</a> to create
JSF managed beans and EJBs for the entity classes, as well as a set of Facelets pages
to handle the views for entity class data. The final section of the tutorial,
<a href="#explore">Exploring the Application</a>, is optional, and provides numerous
exercises to help you to better understand the application and become more familiar with
the IDE.</p>
<img src="../../../images_www/articles/73/netbeans-stamp-80-74-73.png" class="stamp" alt="Content on this page applies to NetBeans IDE 7.2, 7.3, 7.4 and 8.0" title="Content on this page applies to the NetBeans IDE 7.2, 7.3, 7.4 and 8.0" >
<h4>Contents</h4>
<ul class="toc">
<li><a href="#createDB">Creating the Database</a></li>
<li><a href="#examineDB">Examining the Database Structure</a></li>
<li><a href="#createProject">Creating the Web Application Project</a></li>
<li><a href="#generateEntity">Generating the Entity Classes from the Database</a></li>
<li><a href="#jsfPagesEntityClasses">Generating JSF Pages From Entity Classes</a></li>
<li><a href="#explore">Exploring the Application</a>
<ul>
<li><a href="#completedProject">Examining the Completed Project</a></li>
<li><a href="#populateDB">Populating the Database with an SQL Script</a></li>
<li><a href="#editorSupport">Exploring Editor Support in Facelets Pages</a></li>
<li><a href="#dbIntegrity">Exploring Database Integrity with Field Validation</a></li>
<li><a href="#editEntity">Editing Entity Classes</a></li>
</ul></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
<li><a href="#seeAlso">See Also</a></li>
</ul>
<p id="requiredSoftware">To complete this tutorial, you need the following software and resources.</p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td>
<td class="tbltd1">7.2, 7.3, 7.4, 8.0, Java EE bundle</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java Development Kit (JDK)</a></td>
<td class="tbltd1">7 or 8</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://glassfish.dev.java.net/">GlassFish Server Open Source Edition</a></td>
<td class="tbltd1">3.x, 4.x</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fmysql-consult.zip">mysql-consult.zip</a> (MySQL)
<br><em class="margin-around" style="margin-left:6em">or</em><br>
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fjavadb-consult.zip">javadb-consult.zip</a> (JavaDB)</td>
<td class="tbltd1">n/a</td>
</tr>
</tbody>
</table>
<p class="notes"><strong>Notes:</strong></p>
<div class="indent">
<ul>
<li>The NetBeans IDE Java EE bundle also includes the GlassFish server, a Java EE-compliant server,
which you require for this tutorial.</li>
<li>For the solution project to this tutorial, download
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FConsultingAgencyJSF20.zip">ConsultingAgencyJSF20.zip</a>.</li>
</ul>
</div>
<br>
<h2 id="createDB">Creating the Database</h2>
<p>This tutorial uses a consulting agency database called <code>consult</code>. The database
is not included when you install the IDE so you need to first create the database to follow
this tutorial.</p>
<p>The <code>consult</code> 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 <code>consult</code> 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.</p>
<p><strong class="notes">Notes:</strong></p>
<ul>
<li>This tutorial uses the MySQL database server but you can also complete the tutorial
using the JavaDB database server. To create the database in JavaDB, download and
extract the <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fjavadb-consult.zip">javadb-consult.zip</a>
archive. The archive contains SQL scripts for creating, dropping, and populating the
<code>consult</code> database.</li>
<li>For more information on configuring the IDE to work with MySQL, see the
<a href="../ide/mysql.html">Connecting to a MySQL Database</a> tutorial.</li>
<li>For more information on configuring the IDE to work with JavaDB, see the
<a href="../ide/java-db.html">Working with the Java DB (Derby) Database</a> tutorial.</li>
</ul>
<div class="feedback-box float-left" style="width: 678px; margin: 0 0 10px 10px">
<p><strong class="alert">MySQL with GlassFish Combination:</strong></p>
<p>If you are using MySQL, and are using
GlassFish v3 or Open Source Edition 3.0.1, you must ensure that your database
is password-protected. (For more information, see GlassFish
<a href="https://java.net/jira/browse/GLASSFISH-12221"
target="_blank">Issue 12221</a>.) If you are using the default MySQL
<code>root</code> account with an empty password, you can set the password
from a command-line prompt.
<br><br>
For example, to set your password to <code><em>nbuser</em></code>, in a
command-line prompt enter the following commands.</p>
<pre class="examplecode" style="width: 658px;">
shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('<em>nbuser</em>') WHERE User = 'root';
mysql> FLUSH PRIVILEGES;</pre>
<p>If you receive a '<code>mysql: command not found</code>' error, then the
<code>mysql</code> command has not been added to your <code>PATH</code>
environment variable. You can instead call the command by entering the
full path to your MySQL installation's <code>bin</code> directory. For
example, if the <code>mysql</code> command is located on your computer
at <code>/usr/local/mysql/bin</code>, enter the following:</p>
<pre class="examplecode" style="width: 658px;">shell> /usr/local/mysql/bin/mysql -u root</pre>
<p>For more information, see the offical MySQL Reference Manual:</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/default-privileges.html"
target="_blank">Securing the Initial MySQL Accounts</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/invoking-programs.html"
target="_blank">4.2.1. Invoking MySQL Programs</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/setting-environment-variables.html"
target="_blank">4.2.4. Setting Environment Variables</a></li>
</ul>
</div>
<br style="clear: both;"/>
<br>
<p>Perform the following steps to create a database and connect to it from the IDE.</p>
<ol style="margin-top:0">
<li>Download <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fmysql-consult.zip">mysql-consult.zip</a>
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.</li>
<li>In the Services window, expand the Databases node, right-click the MySQL node and
choose Start Server.</li>
<li>Right-click the MySQL Server node and choose Create Database.</li>
<li>Type <strong>consult</strong> as the Database Name in the Create MySQL Database
dialog. Click OK. A new node appears under the Databases node
(<code>jdbc:mysql://localhost:3306/consult [root on Default schema]</code>).</li>
<li>Right-click the new node and choose Connect.</li>
<li>Choose File &gt; Open File from the main menu and navigate to the extracted file
<code>mysql_create_consult.sql</code>. Click Open. The file automatically
opens in the SQL editor.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/run-sql-script.png"
alt="Screenshot of SQL editor" class="margin-around b-all"
title="Open SQL files in the IDE's editor"></li>
<li>Make sure that the <code>consult</code> database is selected in the Connection drop-down list
in the SQL editor toolbar, then click the Run SQL (
<img src="../../../images_www/articles/72/web/jsf20-crud/run-sql-btn.png" alt="Run SQL button">
) button.
<p>When you click Run SQL, the following output appears in the Output window.</p>
<img src="../../../images_www/articles/72/web/jsf20-crud/run-sql-output.png"
alt="Screenshot of Output window" class="margin-around b-all"
title="Output window provides information on SQL execution"></li>
</ol>
<br>
<h2 id="examineDB">Examining the Database Structure</h2>
<p>To confirm that 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.</p>
<div class="indent">
<img src="../../../images_www/articles/72/web/jsf20-crud/services-window-tables.png"
alt="Screenshot of Services window" class="margin-around b-all"
title="Services window displays database connections, tables, table columns, indexes, and foreign keys">
</div>
<p class="notes"><strong>Note:</strong> If you do not see any tables under the Tables
node, right-click the Tables node and choose Refresh.</p>
<p>Looking at the structure of the <code>consult</code> 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.</p>
<img src="../../../images_www/articles/72/web/jsf20-crud/diagram_consult.png"
class="margin-around b-all" alt="Entity-relationship diagram of consult database"
title="Entity-relationship diagram of consult database"
id="er-diagram">
<p>The following table describes the tables found in the <code>consult</code> database.</p>
<table class="indent" style="width: 744px">
<tr>
<th class="tblheader" scope="col">Database Table</th>
<th class="tblheader" scope="col">Description</th>
<th class="tblheader" scope="col">Design Features</th>
</tr>
<tr>
<td class="tbltd1">CLIENT</td>
<td class="tbltd0">A client of the consulting agency</td>
<td class="tbltd0">Non-generated, composite primary key (whose fields
do not constitute a foreign key)</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT</td>
<td class="tbltd0">An employee of the consulting agency whom clients
can hire on a contract basis</td>
<td class="tbltd0">Includes a resume field of type LONG VARCHAR</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT_STATUS</td>
<td class="tbltd0">A consultant's status with the consulting agency
(for example, Active and Inactive are possible statuses)</td>
<td class="tbltd0">Non-generated primary key of type CHAR</td>
</tr>
<tr>
<td class="tbltd1">RECRUITER</td>
<td class="tbltd0">An employee of the consulting agency responsible
for connecting clients and consultants</td>
<td class="tbltd0">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1">PROJECT</td>
<td class="tbltd0">A project that a client staffs with consultants of
the consulting agency</td>
<td class="tbltd0">Non-generated, composite primary key that includes
two fields constituting a foreign key to the CLIENT table</td>
</tr>
<tr>
<td class="tbltd1">BILLABLE</td>
<td class="tbltd0">A set of hours worked by a consultant on a project,
for which the consulting agency bills the relevant client</td>
<td class="tbltd0">Includes an artifact field of type CLOB</td>
</tr>
<tr>
<td class="tbltd1">ADDRESS</td>
<td class="tbltd0">A client's billing address</td>
<td class="tbltd0">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1">PROJECT_CONSULTANT</td>
<td class="tbltd0">Join table indicating which consultants are currently
assigned to which projects</td>
<td class="tbltd0">Cross-references PROJECT and CONSULTANT, the former
having a composite primary key</td>
</tr>
</table>
<br>
<p>The <code>consult</code> 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 <code>consult</code> database. (Inverse
relationships are not shown.)</p>
<table id="relationships" class="indent" style="width: 744px">
<tr>
<th class="tblheader" scope="col">Entity</th>
<th class="tblheader" scope="col">Related Entity</th>
<th class="tblheader" scope="col">Relationship Information</th>
<th class="tblheader" scope="col">Description</th>
</tr>
<tr>
<td class="tbltd1">CLIENT</td>
<td class="tbltd0">RECRUITER</td>
<td class="tbltd0">nullable one-to-one with manual editing; nullable one-to-many
if not edited</td>
<td class="tbltd0">CLIENT has many RECRUITERs and RECRUITER has zero or one CLIENT
(if not manually edited)</td>
</tr>
<tr>
<td class="tbltd1">CLIENT</td>
<td class="tbltd0">ADDRESS</td>
<td class="tbltd0">non-nullable one-to-one</td>
<td class="tbltd0">CLIENT has one ADDRESS and ADDRESS has zero or one CLIENT</td>
</tr>
<tr>
<td class="tbltd1">CLIENT</td>
<td class="tbltd0">PROJECT</td>
<td class="tbltd0">non-nullable one-to-many; in a Project entity, the value of the
client field is part of the Project's primary key</td>
<td class="tbltd0">CLIENT has many PROJECTs and PROJECT has one CLIENT</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT</td>
<td class="tbltd0">PROJECT</td>
<td class="tbltd0">many-to-many</td>
<td class="tbltd0">CONSULTANT has many PROJECTs and PROJECT has many CONSULTANTs</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT</td>
<td class="tbltd0">BILLABLE</td>
<td class="tbltd0">non-nullable one-to-many</td>
<td class="tbltd0">CONSULTANT has many BILLABLEs and BILLABLE has one CONSULTANT</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT_STATUS</td>
<td class="tbltd0">CONSULTANT</td>
<td class="tbltd0">non-nullable one-to-many</td>
<td class="tbltd0">CONSULTANT_STATUS has many CONSULTANTs and CONSULTANT has one
CONSULTANT_STATUS</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT</td>
<td class="tbltd0">RECRUITER</td>
<td class="tbltd0">nullable one-to-many</td>
<td class="tbltd0">CONSULTANT has zero or one RECRUITER and RECRUITER has many
CONSULTANTs</td>
</tr>
<tr>
<td class="tbltd1">BILLABLE</td>
<td class="tbltd0">PROJECT</td>
<td class="tbltd0">non-nullable one-to-many</td>
<td class="tbltd0">BILLABLE has one PROJECT and PROJECT has many BILLABLEs</td>
</tr>
</table>
<p>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.</p>
<h2 id="createProject">Creating the Web Application Project</h2>
<p>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.</p>
<ol>
<li>Choose File &gt; New Project (Ctrl-Shift-N; &#8984-Shift-N on Mac) from the main menu.</li>
<li>Select Web Application from the Java Web category. Click Next.</li>
<li>Type <code>ConsultingAgency</code> for the project name and set the project
location. Click Next.</li>
<li>Set the server to GlassFish and set the Java EE Version to Java EE 6 Web or Java EE 7 Web. Click Next.</li>
<li>In the Frameworks panel, select the JavaServer Faces option. Click Finish.</li>
</ol>
<p>When you click Finish, the IDE generates the web application project and opens
<code>index.xhtml</code> in the editor.</p>
<h2 id="generateEntity">Generating the Entity Classes from the Database</h2>
<p>After connecting to a database in 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.</p>
<ol>
<li>In the Projects window, right-click the <code>ConsultingAgency</code> project node,
and choose New &gt; Entity Classes from Database. (If this option is not listed,
choose Other. Then, in the File wizard, select the Persistence category, then Entity
Classes from Database.)</li>
<li>Select New Data Source from the Data Source drop-down list to open the Create Data Source dialog.</li>
<li>Type <code>jdbc/consult</code> as the JNDI Name and select the <code>jdbc:mysql://localhost:3306/consult</code> connection
as the Database Connection.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/create-datasource.png"
alt="Create Datasource dialog box" class="margin-around b-all"
title="Specify a JNDI name and database connection to create a datasource"></li>
<li>Click OK to close the dialog box and return to the wizard. The tables in the <code>consult</code>
database appear in the Available Tables listbox.</li>
<li>Click the Add All button to select all tables contained in the database. Click Next.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/new-entities-wizard.png"
alt="New Entities from Database wizard" class="margin-around b-all"></li>
<li>Type <code>jpa.entities</code> as the Package name. </li>
<li>Confirm that the checkboxes to generate named queries and create a persistence unit are selected.
Click Finish.</li>
</ol>
<p>When you click Finish, the IDE generates the entity classes in the <code>jpa.entities</code>
package of the project.</p>
<p>When using the wizard to create entity classes from a database, the IDE examines the
relationships between database tables. In the Projects window, if you expand the
<code>jpa.entities</code> package node, you can see that the IDE generated an entity
class for each table except for the <code>PROJECT_CONSULTANT</code> table. The IDE
did not create an entity class for <code>PROJECT_CONSULTANT</code> because the table
is a join table.</p>
<div class="indent">
<img src="../../../images_www/articles/72/web/jsf20-crud/projects-window-entities.png"
alt="screenshot of Projects window" class="margin-around b-all"
title="screenshot of Projects window showing generated entity classes">
</div>
<p>The IDE also generated two additional classes for the tables with composite primary keys:
<code>CLIENT</code> and <code>PROJECT</code>. The primary key classes for these tables
(<code>ClientPK.java</code> and <code>ProjectPK.java</code>) have <code>PK</code> appended
to the name.</p>
<p>If you look at the generated code for the entity classes you can see that the wizard added
<code>@GeneratedValue</code> annotations to the auto-generated ID fields and <code>@Basic(optional = "false")</code> annotations to some of the fields in the entity classes.
Based on the <code>@Basic(optional = "false")</code> annotations, the JSF Pages from Entity Classes wizard can generate code that
includes checks to prevent non-nullable column violations for those fields.</p>
<br>
<h2 id="jsfPagesEntityClasses">Generating JSF Pages From Entity Classes</h2>
<p>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 is
based on persistence annotations contained in the entity classes.</p>
<p>For each entity class the wizard generates the following files.</p>
<ul>
<li>a stateless session bean that extends <tt>AbstractFacade.java</tt></li>
<li>a JSF session-scoped, managed bean</li>
<li>a directory containing four Facelets files for CRUD capabilities (<code>Create.xhtml</code>,
<code>Edit.xhtml</code>, <code>List.xhtml</code>, and <code>View.xhtml</code>)</li>
</ul>
<p>The wizard also generates the following files.</p>
<ul>
<li>the <tt>AbstractFacade.java</tt> class that contains the business logic for creation, retrieval, modification
and removal of entity instances</li>
<li>utility classes used by the JSF managed beans (<code>JsfUtil</code>,
<code>PaginationHelper</code>)</li>
<li>a properties bundle for localized messages, and a corresponding entry in the
project's Faces configuration file (A <code>faces-config.xml</code> file is
created if one does not already exist.)</li>
<li>auxiliary web files, including a default stylesheet for rendered components,
and a Facelets template file</li>
</ul>
<p>To generate the JSF pages:</p>
<ol>
<li>In the Projects window, right-click the project node and choose New &gt; JSF Pages
from Entity Classes to open the wizard. (If this option is not listed, choose Other.
Then, in the File wizard, select the JavaServer Faces category, then JSF Pages
from Entity Classes.)
<p>
The Available Entity Classes box lists the seven entity classes contained in the
project. The box does not list the embeddable classes (<code>ClientPK.java</code>
and <code>ProjectPK.java</code>).</p></li>
<li>Click Add All to move all the classes to the Selected Entity Classes box.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/newjsf-wizard.png"
alt="New JSF Pages from Entity Classes wizard" class="margin-around b-all"
title="New JSF Pages from Entity Classes wizard displays all entity classes contained in project">
<br>
Click Next.</li>
<li>In Step 3 of the wizard, Generate JSF Pages and Classes, type <code>jpa.session</code>
for the JPA Session Bean Package.</li>
<li>Type <code>jsf</code> for the JSF Classes Package.</li>
<li>Enter '<code>/resources/Bundle</code>' into the Localization Bundle Name field. This will
generate a package named <code>resources</code> which the <code>Bundle.properties</code>
file will reside in. (If you leave this blank, the properties bundle will be created
in the project's default package.)
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/newjsf-wizard2.png"
alt="New JSF Pages from Entity Classes wizard, step 3" class="margin-around b-all"
title="Specify package and folder names for generated files">
<p class="tips">To let the IDE better accommodate your project conventions, you can
customize any files generated by the wizard. Click the Customize Template link to
modify the file templates used by the wizard.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/customize-template.png"
alt="Customize Template drop-down list" class="margin-around"
title="Customize templates for files generated by the wizard">
<br>
In general, you can access and make changes to all templates maintained by the IDE
using the Template Manager (Tools &gt; Templates).</p></li>
<li>Click Finish. The IDE generates the stateless session beans in the <code>jpa.session</code>
package, and the JSF session-scoped, managed beans in the <code>jsf</code> package. Each
stateless session bean 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 managed bean implements the <code>javax.faces.convert.Converter</code> interface and
performs the work of converting instances of the corresponding entity class to <code>String</code>
objects and vice versa.</li>
</ol>
<p>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 <code>Create.xhtml</code>, <code>Edit.xhtml</code>,
<code>List.xhtml</code> and <code>View.xhtml</code>. The IDE also modified the <code>index.xhtml</code>
file by inserting links to each of the <code>List.xhtml</code> pages.</p>
<div class="indent">
<img src="../../../images_www/articles/72/web/jsf20-crud/projects-jsfpages.png"
alt="Screenshot of Web Pages directory in Projects window" class="margin-around b-all"
title="Facelets pages for each entity class are generated by the wizard">
</div>
<p>Each JSF managed bean is specific to the four corresponding Facelets files and includes code
that invokes methods in the appropriate session bean.</p>
<p>Expand the <code>resources</code> folder node to locate the default <code>jsfcrud.css</code>
stylesheet that was generated by the wizard. If you open the application welcome page
(<code>index.xhtml</code>) or the Facelets template file (<code>template.xhtml</code>)
in the editor, you will see that it contains a reference to the stylesheet.</p>
<div class="indent">
<pre class="examplecode">&lt;h:outputStylesheet name=&quot;css/jsfcrud.css&quot;/&gt;</pre>
</div>
<p>The Facelets template file is used by each of the four Facelets files for each entity class.</p>
<p>If you expand the Source Packages node you can see the session beans, JSF managed beans,
utility classes, and properties bundle that the wizard generated.</p>
<div class="indent">
<img src="../../../images_www/articles/72/web/jsf20-crud/projects-generated-classes70.png"
alt="screenshot of Source Packages directory in Projects window" class="margin-around b-all"
title="screenshot of Source Packages directory in Projects window showing classes generated by wizard">
</div>
<p>The wizard also generated a Faces Configuration file (<code>faces-config.xml</code>) in
order to register the location of the properties bundle. If you expand the Configuration
Files node and open <code>faces-config.xml</code> in the XML editor, you can see that
the following entry is included.</p>
<div class="indent">
<pre class="examplecode">&lt;application&gt;
&lt;resource-bundle&gt;
&lt;base-name&gt;/resources/Bundle&lt;/base-name&gt;
&lt;var&gt;bundle&lt;/var&gt;
&lt;/resource-bundle&gt;
&lt;/application&gt;</pre>
</div>
<p>Also, if you expand the new <code>resources</code> package, you'll find the <code>Bundle.properties</code>
file that contains messages for the client's default language. The messages have been
derived from the entity class properties.</p>
<p class="tips">To add a new property bundle, right-click the <code>Bundle.properties</code> file
and choose Customize. The Customizer dialog enables you to add new locales to your application.</p>
<br>
<h2 id="explore">Exploring the Application</h2>
<p>Now that your project contains entity classes, EJB session beans to control the
entity classes, and a JSF-powered front-end to display and modify database, try
running the project to see the results.</p>
<p>The following is a series of short, optional exercises that help you to become familiar
with the application, as well as the features and functionality offered to you by
the IDE.</p>
<ul>
<li><a href="#completedProject">Examining the Completed Project</a></li>
<li><a href="#populateDB">Populating the Database with an SQL Script</a></li>
<li><a href="#editorSupport">Exploring Editor Support in Facelets Pages</a></li>
<li><a href="#dbIntegrity">Exploring Database Integrity with Field Validation</a></li>
<li><a href="#editEntity">Editing Entity Classes</a></li>
</ul>
<div class="indent">
<h3 id="completedProject">Examining the Completed Project</h3>
<ol>
<li>To run the project, either right-click the project node in the Projects window
and choose Run, or click the Run Project (
<img src="../../../images_www/articles/72/web/jsf20-crud/run-project-btn.png" alt="Run Project button">
) button in the main toolbar.
<p>
When the application's welcome page displays, you are provided with a list of
links enabling you to view entries contained in each database table.
</p>
<img src="../../../images_www/articles/72/web/jsf20-crud/welcome-page-links.png"
alt="ConsultingAgency welcome page in browser" class="margin-around b-all"
title="Links to display database contents for each table">
<p>
The links were added to the welcome page (<code>index.xhtml</code>) when you
completed the JSF Pages from Entity Classes wizard. They are provided as
entry points into the Facelets pages that provide CRUD functionality on the
Consulting Agency database.</p>
<pre class="examplecode">
&lt;h:body&gt;
Hello from Facelets
&lt;h:form&gt;
&lt;h:commandLink action=&quot;/address/List&quot; value=&quot;Show All Address Items&quot;/&gt;
&lt;/h:form&gt;
&lt;h:form&gt;
&lt;h:commandLink action=&quot;/billable/List&quot; value=&quot;Show All Billable Items&quot;/&gt;
&lt;/h:form&gt;
&lt;h:form&gt;
&lt;h:commandLink action=&quot;/client/List&quot; value=&quot;Show All Client Items&quot;/&gt;
&lt;/h:form&gt;
&lt;h:form&gt;
&lt;h:commandLink action=&quot;/consultant/List&quot; value=&quot;Show All Consultant Items&quot;/&gt;
&lt;/h:form&gt;
&lt;h:form&gt;
&lt;h:commandLink action=&quot;/consultantStatus/List&quot; value=&quot;Show All ConsultantStatus Items&quot;/&gt;
&lt;/h:form&gt;
&lt;h:form&gt;
&lt;h:commandLink action=&quot;/project/List&quot; value=&quot;Show All Project Items&quot;/&gt;
&lt;/h:form&gt;
&lt;h:form&gt;
&lt;h:commandLink action=&quot;/recruiter/List&quot; value=&quot;Show All Recruiter Items&quot;/&gt;
&lt;/h:form&gt;
&lt;/h:body&gt;</pre></li>
<li>Click the '<code>Show All Consultant Items</code>' link. Looking at the code above, you
can see that the target page is <code>/consultant/List.xhtml</code>. (In JSF 2.x, the file
extension is inferred due to implicit navigation.)
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/empty-consultants-list.png"
alt="Consultants page" class="margin-around b-all" title="Consultants table is currently empty">
<br>
The database currently doesn't contain any sample data. You can add data manually
by clicking the '<code>Create New Consultant</code>' link and using the provided
web form. This triggers the <code>/consultant/Create.xhtml</code> page to display.
You can also run an SQL script in the IDE to populate tables with sample data. The
following sub-sections explore both options.</li>
</ol>
<p>You can click the index link to return to the links listed in the welcome page.
The links provide you with a view of the data held in each database table and
trigger the <code>List.xhtml</code> file for each entity folder to display. As
is later demonstrated, after you add data to the tables, other links will display
for each entry enabling you to view (<code>View.xhtml</code>), edit (<code>Edit.xhmtl</code>),
and destroy data for a single table record.</p>
<p class="notes"><strong>Note.</strong> If the application fails to deploy, see the
<a href="#troubleshooting">troubleshooting section</a> below.
(Also see the troubleshooting section of <a href="mysql-webapp.html#troubleshoot">Creating a Simple Web Application Using a MySQL Database</a>.)</p>
<h3 id="populateDB">Populating the Database with an SQL Script</h3>
<p>Run the provided script, which generates sample data for the database tables. The script
(<code>mysql_insert_data_consult.sql</code>) is included in the Consulting Agency Database
zip file which you can download from the <a href="#requiredSoftware">required software
table</a>.</p>
<p>Depending on the database server you are working with (MySQL or JavaDB), you can run the
provided script, which generates sample data for the database tables. For MySQL, this is
the <code>mysql_insert_data_consult.sql</code> script. For JavaDB, this is the
<code>javadb_insert_data_consult.sql</code> script. Both scripts are included in their
respective archives, which can be downloaded from the <a href="#requiredSoftware">required
software table</a>.</p>
<ol>
<li>Choose File &gt; Open File from the main menu, then navigate to the location of the
script on your computer. Click Open. The file automatically opens in the IDE's SQL
editor.</li>
<li>Make sure that the <code>consult</code> database is selected in the Connection
drop-down list in the SQL editor toolbar.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/run-sql-insert.png"
alt="screenshot of SQL editor and insert data script" class="margin-around b-all"
title="Open the script in the IDE's SQL editor">
<p>
Either right-click in the editor and choose Run Statement, or click the Run SQL (
<img src="../../../images_www/articles/72/web/jsf20-crud/run-sql-btn.png" alt="Run SQL button">
) button. You can see the result of the script execution in the Output window.</p></li>
<li>Restart the GlassFish server. This is a necessary step to enable the server to reload and cache
the new data contained in the <code>consult</code> database. To do so, click the GlassFish server
tab in the Output window (The GlassFish server tab displays the server log.), then click the
Restart Server ( <img src="../../../images_www/articles/72/web/jsf20-crud/glassfish-restart.png"
alt="Restart Server button"> ) button in the left margin. The server stops, then restarts.</li>
<li>Run the project again and click the '<code>Show All Consultant Items</code>' link. You will
see that the list is no longer empty.
<br>
<a href="../../../images_www/articles/72/web/jsf20-crud/consultants-list.png" rel="lytebox"
title="Facelets page displays entries contained in Consultants table" id="consultantsList">
<img src="../../../images_www/articles/72/web/jsf20-crud/consultants-list-small.png"
alt="Consultants page displaying table entries" class="margin-around b-all"></a>
<div class="feedback-box float-left" style="width: 683px;">
<h3>NetBeans Database Support</h3>
<p>You can use the IDE's database table viewer to display and modify table
data maintained directly in the database. For example, right-click the
<code>consultant</code> table in the Services window, and choose View
Data.</p>
<img src="../../../images_www/articles/72/web/jsf20-crud/view-data.png"
alt="Services window - right-click menu of database table" class="margin-around b-all"
title="Choose View Data from the right-click menu of database tables">
<p>The SQL query used to perform the action displays in the upper portion
of the editor, and a graphical view of the table displays beneath.</p>
<a href="../../../images_www/articles/72/web/jsf20-crud/view-data-table.png" rel="lytebox"
title="Use the graphical view of database tables to view and modify table data">
<img src="../../../images_www/articles/72/web/jsf20-crud/view-data-table-small.png"
alt="SQL editor displaying database data" class="margin-around b-all"></a>
<p>Double-click inside table cells to perform inline modifications to data.
Click the Commit Records ( <img src="../../../images_www/articles/72/web/jsf20-crud/commit-records-icon.png" alt="Commit Records icon"> )
icon to commit changes to the database.</p>
<p>
The graphical view provides much more functionality.
See <a href="../../docs/ide/database-improvements-screencast.html">Database Support in NetBeans IDE</a>
for more information.</p>
</div>
<br style="clear: both;"/></li>
</ol>
<h3 id="editorSupport">Exploring Editor Support in Facelets Pages</h3>
<ol>
<li>Open the <code>/consultant/List.xhtml</code> page in the editor. Line 8 indicates that
the page relies on the Facelets <code>template.xhtml</code> file to render.
<pre class="examplecode">&lt;ui:composition template=&quot;/template.xhtml&quot;&gt;</pre>
<p class="tips">To display line numbers, right-click in the editor's left margin and
choose Show Line Numbers.</p></li>
<li>Use the IDE's Go to File dialog to open <code>template.xhtml</code>. Press Alt-Shift-O
(Ctrl-Shift-O on Mac), then begin typing <code>template</code>.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/go-to-file.png"
alt="Go to File dialog" class="margin-around b-all"
title="Use the Go to File dialog to quickly open project files">
<p>Click OK (or press Enter).</p></li>
<li>The template applies the <code>&lt;ui:insert&gt;</code> tags to insert content from
other files into its title and body. Place your cursor on the <code>&lt;ui:insert&gt;</code>
tag, then press Ctrl-Space to invoke a documentation popup window.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/doc-popup.png"
alt="Documentation popup displayed in editor" class="margin-around b-all"
title="Press Ctrl-Space to invoke a documentation popup on Facelets tags">
<p>You can press Ctrl-Space on JSF tags and their attributes to invoke a documentation
pop-up. The documentation you see is taken from the descriptions provided in the
official <a href="http://javaserverfaces.java.net/nonav/docs/2.1/vdldocs/facelets/index.html">JSF
Tag Library Documentation</a>.</p></li>
<li>Switch back to the <code>List.xhtml</code> file (press Ctrl-Tab). The
<code>&lt;ui:define&gt;</code> tags are used to define the content that will
be applied to the template's title and body. This pattern is used for all four
Facelets files (<code>Create.xhtml</code>, <code>Edit.xhtml</code>, <code>List.xhtml</code>,
and <code>View.xhtml</code>) generated for each entity class.</li>
<li>Place your cursor on any of the EL expressions used for localized messages contained
in the <code>Bundle.properties</code> file. Press Ctrl-Space to view the localized
message.
<br>
<a href="../../../images_www/articles/72/web/jsf20-crud/localized-messages.png" rel="lytebox"
title="View localized messages using editor code completion support">
<img src="../../../images_www/articles/72/web/jsf20-crud/localized-messages-small.png"
alt="Code completion pop-up of messages from properties bundle"
class="margin-around b-all"></a>
<p>In the above image, you can see that the EL expression resolves to '<code>List</code>',
which is applied to the template title and can be verified from the page rendered in the
browser.</p></li>
<li>Scroll to the bottom of the file and locate the code for the <code>Create New Consultant</code>
link (Line 92). This is as follows:
<pre class="examplecode">
&lt;h:commandLink action=&quot;#{consultantController.prepareCreate}&quot; value=&quot;#{bundle.ListConsultantCreateLink}&quot;/&gt;</pre></li>
<li>Press Ctrl-Space on the <code>commandLink</code>'s <code>action</code> attribute to
invoke the documentation pop-up.
<br><br>
The <code>action</code> attribute indicates the method that handles the request when
the link is clicked in the browser. The following documentation is provided:
<br><br>
<div class="indent" style="width:680px">
<em>MethodExpression representing the application action to invoke when this
component is activated by the user. The expression must evaluate to a public
method that takes no parameters, and returns an Object (the toString() of
which is called to derive the logical outcome) which is passed to the
NavigationHandler for this application.</em></div>
<br>
In other words, the <code>action</code> value typically refers to a method in a
JSF managed bean that evaluates to a <code>String</code>. The string is then used
by JSF's <code>NavigationHandler</code> to forward the request to the appropriate
view. You verify this in the following steps.</li>
<li>Place your cursor on <code>consultantController</code> and press Ctrl-Space. The
editor's code completion indicates that <code>consultantController</code> is a
JSF managed bean.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/code-completion-managed-bean.png"
alt="Code completion invoked in editor" class="margin-around b-all"
title="Code completion is provided for JSF managed beans"></li>
<li>Move your cursor to <code>prepareCreate</code> and press Ctrl-Space. Code completion
lists methods contained in the <code>ConsultantController</code> managed bean.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/code-completion-properties.png"
alt="Code completion invoked in editor" class="margin-around b-all"
title="Code completion is provided for class methods"></li>
<li>Press Ctrl (&#8984 on Mac), then hover your mouse over <code>prepareCreate</code>. A
link is formed, enabling you to navigate directly to the <code>prepareCreate()</code>
method in the <code>ConsultantController</code> managed bean.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/editor-navigation.png"
alt="Link displayed in editor" class="margin-around b-all"
title="Use editor navigation to quickly navigate source code"></li>
<li>Click the link and view the <code>prepareCreate()</code> method (displayed below).
<pre class="examplecode">
public String prepareCreate() {
current = new Consultant();
selectedItemIndex = -1;
return &quot;Create&quot;;
}</pre>
The method returns <code>Create</code>. The <code>NavigationHandler</code>
gathers information behind the scenes, and applies the <code>Create</code>
string to the path which targets the view sent in response to the request:
<code>/consultant/<strong>Create</strong>.xhtml</code>. (In JSF 2.x, the file
extension is inferred due to implicit navigation.)</li>
</ol>
<h3 id="dbIntegrity">Exploring Database Integrity with Field Validation</h3>
<ol>
<li>From the <a href="#consultantsList">Consultants List page</a> in the browser,
click the '<code>Create New Consultant</code>' link. As demonstrated in the
previous sub-section, this triggers the <code>/consultant/Create.xhtml</code>
page to render.</li>
<li>Enter the following details into the form. For the time being, leave both <code>RecruiterId</code>
and <code>StatusId</code> fields blank.
<br><br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Field</th>
<th class="tblheader" scope="col">Value</th>
</tr>
<tr>
<td class="tbltd1">ConsultantId</td>
<td class="tbltd1">2</td>
</tr>
<tr>
<td class="tbltd1">Email</td>
<td class="tbltd1">jack.smart@jsfcrudconsultants.com</td>
</tr>
<tr>
<td class="tbltd1">Password</td>
<td class="tbltd1">jack.smart</td>
</tr>
<tr>
<td class="tbltd1">HourlyRate</td>
<td class="tbltd1">75</td>
</tr>
<tr>
<td class="tbltd1">BillableHourlyRate</td>
<td class="tbltd1">110</td>
</tr>
<tr>
<td class="tbltd1">HireDate</td>
<td class="tbltd1">07/22/2008</td>
</tr>
<tr>
<td class="tbltd1">Resume</td>
<td class="tbltd1">I'm a great consultant. Hire me - You won't be disappointed!</td>
</tr>
<tr>
<td class="tbltd1">RecruiterId</td>
<td class="tbltd1">---</td>
</tr>
<tr>
<td class="tbltd1">StatusId</td>
<td class="tbltd1">---</td>
</tr>
</tbody>
</table></li>
<li>Click Save. When you do so, a validation error is flagged for the <code>StatusId</code> field.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/create-new-consultant.png"
alt="Create New Consultant page containing sample data" class="margin-around b-all"
title="Enter sample data into the form">
<br>
Why did this happen? Reexamine the <a href="#er-diagram">entity-relationship diagram for the
Consulting Agency database</a>. As stated in the <a href="#relationships">relationships table</a>
above, the <code>CONSULTANT</code> and <code>CONSULTANT_STATUS</code> tables share a non-nullable,
one-to-many relationship. Therefore, every entry in the <code>CONSULTANT</code> table must contain
a reference to an entry in the <code>CONSULTANT_STATUS</code> table. This is denoted by the
<code>consultant_fk_consultant_status</code> foreign key that links the two tables.
<p class="tips">You can view foreign keys held by tables by expanding a table's Foreign Keys
node in the Services window (Ctrl-5; &#8984-5 on Mac).</p>
<img src="../../../images_www/articles/72/web/jsf20-crud/consultant-fk.png"
alt="Services window - foreign keys for consultant table" class="margin-around b-all"
title="Examine foreign key attributes in the Services window"></li>
<li>To overcome the validation error, select <code>entity.ConsultantStatus[statusId=A]</code> from
the <code>StatusId</code> drop-down list.
<br><br>
<strong class="notes">Note: </strong>You can leave the <code>RecruiterId</code> field blank.
As indicated in the <a href="#er-diagram">database entity-relationship diagram</a>, there is
a nullable, one-to-many relationship between the <code>CONSULTANT</code> and <code>RECRUITER</code>
tables, meaning that entries in <code>CONSULTANT</code> do not need to be associated with
a <code>RECRUITER</code> entry.</li>
<li>Click Save. A message displays, indicating that the consultant entry was successfully saved.
If you click <code>Show All Consultant Items</code>, you'll see the new entry listed in the
table.</li>
</ol>
<p>In general, the generated Facelets pages provide errors for user input that introduces:</p>
<ul>
<li>empty fields for non-nullable table cells.</li>
<li>modifications to data that cannot be altered (e.g., primary keys).</li>
<li>insertion of data that is not of the correct type.</li>
<li>modifications to data when a user's view is no longer synchronized with
the database.</li>
</ul>
<h3 id="editEntity">Editing Entity Classes</h3>
<p>In the previous sub-section, you saw how the <code>StatusId</code> drop-down list provided
you with the not-so-user-friendly <code>entity.ConsultantStatus[statusId=A]</code> option.
You may already be aware that the text displayed for each item in this drop-down is a string
representation for each <code>ConsultantStatus</code> entity encountered (i.e., The entity
class' <code>toString()</code> method is called).</p>
<p>This sub-section demonstrates how you can use the editor's code completion, documentation,
and navigation support to make this conclusion. It also has you prepare a more user-friendly
message for the drop-down list.</p>
<ol>
<li id="markup">Open the <code>/consultant/Create.xhtml</code> file in the editor. This is the Create
New Consultant form which you just viewed in the browser. Scroll down to the code for
the <code>StatusId</code> drop-down (shown in <strong>bold</strong> below).
<pre class="examplecode">
&lt;h:outputLabel value=&quot;#{bundle.CreateConsultantLabel_resume}&quot; for=&quot;resume&quot; /&gt;
&lt;h:inputTextarea rows=&quot;4&quot; cols=&quot;30&quot; id=&quot;resume&quot; value=&quot;#{consultantController.selected.resume}&quot; title=&quot;#{bundle.CreateConsultantTitle_resume}&quot; /&gt;
<strong>&lt;h:outputLabel value=&quot;#{bundle.CreateConsultantLabel_statusId}&quot; for=&quot;statusId&quot; /&gt;
&lt;h:selectOneMenu id=&quot;statusId&quot; value=&quot;#{consultantController.selected.statusId}&quot; title=&quot;#{bundle.CreateConsultantTitle_statusId}&quot; required=&quot;true&quot; requiredMessage=&quot;#{bundle.CreateConsultantRequiredMessage_statusId}&quot;&gt;
&lt;f:selectItems value=&quot;#{consultantStatusController.itemsAvailableSelectOne}&quot;/&gt;
&lt;/h:selectOneMenu&gt;</strong>
&lt;h:outputLabel value=&quot;#{bundle.CreateConsultantLabel_recruiterId}&quot; for=&quot;recruiterId&quot; /&gt;
&lt;h:selectOneMenu id=&quot;recruiterId&quot; value=&quot;#{consultantController.selected.recruiterId}&quot; title=&quot;#{bundle.CreateConsultantTitle_recruiterId}&quot; &gt;
&lt;f:selectItems value=&quot;#{recruiterController.itemsAvailableSelectOne}&quot;/&gt;
&lt;/h:selectOneMenu&gt;
&lt;/h:panelGrid&gt;</pre></li>
<li>Examine the <code>value</code> applied to the <code>&lt;f:selectItems&gt;</code> tag.
The <code>value</code> attribute determines the text that displays for each item in
the drop-down list.
<br><br>
Press Ctrl-Space on <code>itemsAvailableSelectOne</code>. The editor's
code completion indicates that the <code>ConsultantStatusController</code>'s
<code>getItemsAvailableSelectOne()</code> method returns an array of
<code>SelectItem</code> objects.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/code-completion-returned-object.png"
alt="Code completion invoked in editor" class="margin-around b-all"
title="Code completion displays returned classes for methods"></li>
<li>Press Ctrl (&#8984 on Mac), then hover your mouse over <code>itemsAvailableSelectOne</code>.
A link is formed, enabling you to navigate directly to the <code>getItemsAvailableSelectOne()</code>
method in the <code>ConsultantStatus</code> entity's source code. Click this link.</li>
<li>Place your cursor on the <code>SelectItem[]</code> return value in the method
signature, and press Ctrl-Space to invoke the documentation pop-up.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/documentation-select-item.png"
alt="Documentation pop-up invoked in Java class" class="margin-around b-all"
title="Press Ctrl-Space to invoke documentation support">
<p class="tips">Click the web browser (
<img src="../../../images_www/articles/72/web/jsf20-crud/web-browser-icon.png"
alt="Web browser icon"> ) icon in the documentation window to open the Javadoc
in an external web browser.</p>
As you can see, the <code>SelectItem</code> class belongs to the JSF framework.
The <code>UISelectOne</code> component, as mentioned in the documentation, is represented
by the <code>&lt;h:selectOneMenu&gt;</code> tag from the markup which you examined in
<a href="#markup">Step 1</a> above.</li>
<li>Press Ctrl (&#8984 on Mac), then hover your mouse over <code>findAll()</code>. A pop-up
appears, displaying the method signature.
<br>
<img src="../../../images_www/articles/72/web/jsf20-crud/method-signature.png"
alt="Pop-up of method signature" class="margin-around b-all"
title="View pop-ups of method signatures in the editor">
<br>
You can see that here <code>ejbFacade.findAll()</code> returns a <code>List</code> of
<code>ConsultantStatus</code> objects.</li>
<li>Navigate to <code>JsfUtil.getSelectItems</code>. Hover your mouse over
<code>getSelectItems</code> and press Ctrl (&#8984 on Mac), then click
the link that displays.
<br><br>
<strong class="notes">Note: </strong>Recall that <code>JsfUtil</code>
is one of the utility classes that was generated when you completed the
<a href="#jsfPagesEntityClasses">JSF Pages from Entity Classes wizard</a>.
<br><br>
The method loops through the list of entities (i.e, the <code>List</code>
of <code>ConsultantStatus</code> objects), creating a <code>SelectItem</code>
for each. As indicated in <strong>bold</strong> below, each <code>SelectItem</code>
is created using the entity object and a <em>label</em> for the object.
<pre class="examplecode">
public static SelectItem[] getSelectItems(List&lt;?&gt; entities, boolean selectOne) {
int size = selectOne ? entities.size() + 1 : entities.size();
SelectItem[] items = new SelectItem[size];
int i = 0;
if (selectOne) {
items[0] = new SelectItem(&quot;&quot;, &quot;---&quot;);
i++;
}
<strong>for (Object x : entities) {
items[i++] = new SelectItem(x, x.toString());
}</strong>
return items;
}</pre>
<p>The label is created using the entity's <code>toString()</code> method, and
is the representation of the object when rendered in the response. (See the
Javadoc definition for the <code>SelectItem(java.lang.Object value, java.lang.String label)</code>
constructor.)</p>
<p>
Now that you have verified that the entity <code>toString()</code> method
is what is rendered in the browser when you view items in a drop-down list,
modify the <code>ConsultantStatus</code> <code>toString()</code> method.</p>
</li>
<li>Open the <code>ConsultantStatus</code> entity class in the editor. Modify the
<code>toString</code> method to return the <code>statusId</code> and
<code>description</code>. These are entity properties which correspond to
the two columns of the <code>CONSULTANT_STATUS</code> table.
<pre class="examplecode">public String toString() {
return <strong>statusId + ", " + description;</strong>
}</pre></li>
<li>Run the project again. When the browser displays the welcome page, click the
<code>Show All Consultant Items</code> link, then click <code>Create New Consultant</code>.
<p>
Inspect the <code>StatusId</code> drop-down. You'll see that it now displays
the status ID and description for the one record contained in the database's
<code>CONSULTANT_STATUS</code> table.</p>
<img src="../../../images_www/articles/72/web/jsf20-crud/drop-down.png"
alt="Browser display of StatusId drop-down list" class="margin-around b-all"
title="StatusId drop-down displays items according to ConsultantStatus entity's toString() method">
</li>
</ol>
</div>
<h2 id="troubleshooting">Troubleshooting</h2>
<p>Depending on your configuration, deploying the application to the server can fail
and you might see the following message in the Output window.
</p>
<pre class="examplecode">GlassFish Server 4 is running.
In-place deployment at /MyDocuments/ConsultingAgency/build/web
GlassFish Server 4, deploy, null, false
/MyDocuments/ConsultingAgency/nbproject/build-impl.xml:1045: The module has not been deployed.
See the server log for details.</pre>
<p>The most common cause for the failure is a problem when generating the JDBC resources on the server.
If this is the case, you will probably see a message similar to the following
in the server log tab in the Output window.
</p>
<pre class="examplecode">Severe: Exception while preparing the app : Invalid resource : jdbc/consult__pm
com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Invalid resource : jdbc/consult__pm</pre>
<p class=tips>If the server log tab is not open you can open the tab by right-clicking the GlassFish Server node in the Services
window and choosing View Domain Server Log.</p>
<p>This application requires two JDBC resources:</p>
<ul>
<li>JDBC Resource or Datasource. The application uses JNDI lookup to locate the JDBC resource.
If you look in the persistence unit (<code>persistence.xml</code>) you can see that
the JNDI name for the JTA data source for this application is <code>jdbc/consult</code>.
<p>The JDBC resource identifies the connection pool that is currently used by the application.</p></li>
<li>JDBC Connection Pool. The connection pool specifies the connection details
for the database, including the location, user name, password.
The connection pool that is used for this application is <code>consultPool</code>.</li>
</ul>
<p>The JDBC resource and connection pool are specified in the <code>glassfish-resources.xml</code> file.
You can open <code>glassfish-resources.xml</code> in the editor by expanding the Server Resources
node in the Projects window and double-clicking the file.
The file will look similar to the following.</p>
<pre class="examplecode">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd"&gt;
&lt;resources&gt;
&lt;jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="consultPool" non-transactional-connections="false" ping="false" pool-resize-quantity="2" pooling="true" res-type="javax.sql.DataSource" statement-cache-size="0" statement-leak-reclaim="false" statement-leak-timeout-in-seconds="0" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false"&gt;
&lt;property name="serverName" value="localhost"/&gt;
&lt;property name="portNumber" value="3306"/&gt;
&lt;property name="databaseName" value="consult"/&gt;
&lt;property name="User" value="root"/&gt;
&lt;property name="Password" value="nb"/&gt;
&lt;property name="URL" value="jdbc:mysql://localhost:3306/consult?zeroDateTimeBehavior=convertToNull"/&gt;
&lt;property name="driverClass" value="com.mysql.jdbc.Driver"/&gt;
/&lt;jdbc-connection-pool&gt;
&lt;jdbc-resource enabled="true" jndi-name="jdbc/consult" object-type="user" pool-name="consultPool"/&gt;
/&lt;resources&gt;</pre>
<p>In <code>glassfish-resources.xml</code> you can see that the JDBC resource <code>jdbc/consult</code>
identifies <code>consultPool</code> as the name of the connection pool.
You can also see the properties for <code>consultPool</code>.
In this application only one datasource and one connection pool are defined in <code>glassfish-resources.xml</code>.
In some cases you might want to specify additional resources, for example, to identify a temporary
data store that is used only for development or for testing.</p>
<p>If the JDBC resource and connection pool were not generated automatically on the server when you tried to the
application, you can perform the following steps to manually create the resources in the GlassFish Admin Console.</p>
<ol>
<li>Open <code>glassfish-resources.xml</code> in the editor if it is not already open.
<p>You will use the property values that are specified in <code>glassfish-resources.xml</code>
when you create the JDBC resource and connection pool.</p></li>
<li>Right-click the GlassFish Server node in the Services window and
choose Open Domain Admin Console in the popup menu to open the GlassFish Console in your browser.</li>
<li>In the Common Tasks navigation panel of the GlassFish Console, expand the
<strong>JDBC</strong> node and the <strong>JDBC Resources</strong> and <strong>JDBC Connection Pools</strong> nodes.
<br>
<a href="../../../images_www/articles/80/web/jsf20-crud/gf-admin-console-lg.png">
<img src="../../../images_www/articles/80/web/jsf20-crud/gf-admin-console-sm.png"
alt="Browser display of GlassFish Admin Console" class="margin-around b-all"
title="Click to see full-size image of GlassFish Admin Console"></a>
<p>You can see the JDBC resources that are currently registered with the server.
You will need to create <code>jdbc/consult</code> and <code>consultPool</code> if
they are not listed under the JDBC node in the Common Tasks navigation panel.
Some JDBC resources were created by default when you installed the server and are displayed
as sub-nodes. </p></li>
<li>Click the <strong>JDBC Connection Pools</strong> node and click New in the New JDBC Connection Pool pane.
<br>
<img src="../../../images_www/articles/80/web/jsf20-crud/gf-new-jdbc-pool1.png"
alt="Browser display of New JDBC Connection Pool pane" class="margin-around b-all"
title="New JDBC Connection Pool pane in the GlassFish Admin Console"></li>
<li>Type <strong>consultPool</strong> as the Pool Name, select
<strong>javax.sql.ConnectionPoolDataSource</strong> as the Resource Type
and select <strong>MySql</strong> as the Database Driver Vendor. Click Next.</li>
<li>In Step 2, locate and specify the values for the <strong>URL</strong>, <strong>username</strong> and <strong>password</strong> properties. Click Finish.
<br>
<img src="../../../images_www/articles/80/web/jsf20-crud/gf-new-jdbc-pool2.png"
alt="Browser display of second panel of New JDBC Connection Pool pane" class="margin-around b-all"
title="New JDBC Connection Pool panel in the GlassFish Admin Console">
<p class="tips">You can find the values for the properties in <code>glassfish-resources.xml</code>.</p>
<p>The new connection pool is created on the server when you click Finish
and a node for the connection pool is displayed under the JDBC Connection Pools node.</p></li>
<li>Click the <strong>JDBC Resources</strong> node in the Common Tasks navigation panel and
click New.</li>
<li>Type <strong>jdbc/consult</strong> for the JNDI Name and select
<strong>consultPool</strong> in the Pool Name drop-down list. Click OK.
<br>
<img src="../../../images_www/articles/80/web/jsf20-crud/gf-new-jdbc-resource.png"
alt="Browser display of New JDBC Resource pane" class="margin-around b-all"
title="New JDBC Resource pane in the GlassFish Admin Console">
<p>The new JDBC resource is created on the server when you click OK
and a node for the resource is displayed under the JDBC Resources node.</p>
<p>In the Service window of the IDE, you can expand the Resources node under the
GlassFish Server and see that IDE added the new resources.
You might need to refresh the view (right-click Resources and choose Refresh)
to view the changes.</p>
<img src="../../../images_www/articles/80/web/jsf20-crud/gf-services-jdbc-resources.png"
alt="screenshot of Services window in the IDE" class="margin-around b-all"
title="JDBC Resources displayed in the Services window of the IDE"></li>
</ol>
<p>For more tips on troubleshooting problems when using MySQL and the IDE, see the following documents:</p>
<ul>
<li><a href="../ide/mysql.html">Connecting to a MySQL Database</a> tutorial.</li>
<li>The troubleshooting section of <a href="mysql-webapp.html#troubleshoot">Creating a Simple Web Application Using a MySQL Database</a></li>
</ul>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback:%20Creating%20a%20JSF%202.0%20CRUD%20Application">Send Feedback on This Tutorial</a>
</div>
<br style="clear:both;" />
<h2 id="seealso">See Also</h2>
<p>For more information about JSF 2.x, see the following resources.</p>
<div class="indent">
<h3>NetBeans Articles and Tutorials</h3>
<ul>
<li><a href="jsf20-intro.html">Introduction to JavaServer Faces 2.x in NetBeans IDE</a></li>
<li><a href="jsf20-support.html">JSF 2.x Support in NetBeans IDE</a></li>
<li><a href="../../samples/scrum-toys.html">Scrum Toys - The JSF 2.0 Complete Sample Application</a></li>
<li><a href="../javaee/javaee-gettingstarted.html">Getting Started with Java EE Applications</a></li>
<li><a href="../../trails/java-ee.html">Java EE & Java Web Learning Trail</a></li>
</ul>
<h3>External Resources</h3>
<ul>
<li><a href="http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html">JavaServer Faces Technology</a> (Official homepage)</li>
<li><a href="http://jcp.org/aboutJava/communityprocess/final/jsr314/index.html">JSR 314 Specification for JavaServer Faces 2.0</a></li>
<li><a href="http://docs.oracle.com/javaee/7/tutorial/doc/jsf-intro.htm">JavaServer Faces Technology</a> chapter in the Java EE 7 Tutorial</li>
<li><a href="http://javaserverfaces.dev.java.net/">GlassFish Project Mojarra</a> (Official reference implementation for JSF 2.x)</li>
<li><a href="http://forums.oracle.com/forums/forum.jspa?forumID=982">OTN Discussion Forums : JavaServer Faces</a></li>
<li><a href="http://www.jsfcentral.com/">JSF Central</a></li>
</ul>
<h3>Blogs</h3>
<ul>
<li><a href="http://www.java.net/blogs/edburns/">Ed Burns</a></li>
<li><a href="http://www.java.net/blogs/driscoll/">Jim Driscoll</a></li>
</ul>
</div>
</body>
</html>