| <!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 > 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"> </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"> </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 > New Project (Ctrl-Shift-N; ⌘-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 > 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 > 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 > 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"><h:outputStylesheet name="css/jsfcrud.css"/></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"><application> |
| <resource-bundle> |
| <base-name>/resources/Bundle</base-name> |
| <var>bundle</var> |
| </resource-bundle> |
| </application></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"> |
| <h:body> |
| Hello from Facelets |
| <h:form> |
| <h:commandLink action="/address/List" value="Show All Address Items"/> |
| </h:form> |
| <h:form> |
| <h:commandLink action="/billable/List" value="Show All Billable Items"/> |
| </h:form> |
| <h:form> |
| <h:commandLink action="/client/List" value="Show All Client Items"/> |
| </h:form> |
| <h:form> |
| <h:commandLink action="/consultant/List" value="Show All Consultant Items"/> |
| </h:form> |
| <h:form> |
| <h:commandLink action="/consultantStatus/List" value="Show All ConsultantStatus Items"/> |
| </h:form> |
| <h:form> |
| <h:commandLink action="/project/List" value="Show All Project Items"/> |
| </h:form> |
| <h:form> |
| <h:commandLink action="/recruiter/List" value="Show All Recruiter Items"/> |
| </h:form> |
| </h:body></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 > 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"><ui:composition template="/template.xhtml"></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><ui:insert></code> tags to insert content from |
| other files into its title and body. Place your cursor on the <code><ui:insert></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><ui:define></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"> |
| <h:commandLink action="#{consultantController.prepareCreate}" value="#{bundle.ListConsultantCreateLink}"/></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 (⌘ 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 "Create"; |
| }</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; ⌘-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"> |
| <h:outputLabel value="#{bundle.CreateConsultantLabel_resume}" for="resume" /> |
| <h:inputTextarea rows="4" cols="30" id="resume" value="#{consultantController.selected.resume}" title="#{bundle.CreateConsultantTitle_resume}" /> |
| <strong><h:outputLabel value="#{bundle.CreateConsultantLabel_statusId}" for="statusId" /> |
| <h:selectOneMenu id="statusId" value="#{consultantController.selected.statusId}" title="#{bundle.CreateConsultantTitle_statusId}" required="true" requiredMessage="#{bundle.CreateConsultantRequiredMessage_statusId}"> |
| <f:selectItems value="#{consultantStatusController.itemsAvailableSelectOne}"/> |
| </h:selectOneMenu></strong> |
| <h:outputLabel value="#{bundle.CreateConsultantLabel_recruiterId}" for="recruiterId" /> |
| <h:selectOneMenu id="recruiterId" value="#{consultantController.selected.recruiterId}" title="#{bundle.CreateConsultantTitle_recruiterId}" > |
| <f:selectItems value="#{recruiterController.itemsAvailableSelectOne}"/> |
| </h:selectOneMenu> |
| </h:panelGrid></pre></li> |
| |
| <li>Examine the <code>value</code> applied to the <code><f:selectItems></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 (⌘ 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><h:selectOneMenu></code> tag from the markup which you examined in |
| <a href="#markup">Step 1</a> above.</li> |
| |
| <li>Press Ctrl (⌘ 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 (⌘ 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<?> 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("", "---"); |
| 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"> |
| <?xml version="1.0" encoding="UTF-8"?> |
| <!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd"> |
| <resources> |
| <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"> |
| <property name="serverName" value="localhost"/> |
| <property name="portNumber" value="3306"/> |
| <property name="databaseName" value="consult"/> |
| <property name="User" value="root"/> |
| <property name="Password" value="nb"/> |
| <property name="URL" value="jdbc:mysql://localhost:3306/consult?zeroDateTimeBehavior=convertToNull"/> |
| <property name="driverClass" value="com.mysql.jdbc.Driver"/> |
| /<jdbc-connection-pool> |
| <jdbc-resource enabled="true" jndi-name="jdbc/consult" object-type="user" pool-name="consultPool"/> |
| /<resources></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&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> |