blob: 418f6b28e18b764bac7295576b4c2ce9db644ae6 [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>データベースからのJavaServer Faces 2.x CRUDアプリケーションの生成 - NetBeans IDEチュートリアル</title>
</head>
<body>
<!-- Copyright (c) 2009, 2010, 2011, Oracle and/or its affiliates. All rights reserved. -->
<h1>データベースからのJavaServer Faces 2.x CRUDアプリケーションの生成</h1>
<p>このチュートリアルでは、NetBeans IDEを使用し、バックエンドのデータベースと対話するWebアプリケーションを作成します。このアプリケーションでは、データベースに格納されたデータを表示および変更できます。この機能は<em>CRUD</em> (作成、読取り、更新、削除)とも呼ばれます。開発するアプリケーションは、次のテクノロジに基づきます。</p>
<ul>
<li><strong>JavaServer Faces (JSF) 2.x</strong>。フロント・エンドのWebページ、検証処理およびリクエスト-レスポンス・サイクルの管理に使用します。</li>
<li><strong>Java Persistence API (JPA) 2.0</strong>。EclipseLinkを使用してデータベースからエンティティ・クラスを生成し、トランザクションを管理します。EclipseLinkはJPAのリファレンス実装であり、GlassFishサーバーのデフォルトの持続性プロバイダです。</li>
<li><strong>Enterprise JavaBeans (EJB) 3.1</strong>。エンティティ・クラスにアクセスするステートレスEJBを提供し、アプリケーションのビジネス・ロジックを格納します。</li>
</ul>
<p>IDEには、アプリケーション用のコードをすべて生成する、2つのウィザードが用意されています。<a href="#generateEntity">データベースからのエンティティ・クラス・ウィザード</a>を使用すると、提供されたデータベースからエンティティ・クラスを生成できます。エンティティ・クラスを作成した後は、<a href="#jsfPagesEntityClasses">エンティティからのJSFページ・クラス・ウィザード</a>を使用して、そのエンティティ・クラスのJSF管理対象BeanとEJB、およびエンティティ・クラス・データのビューを処理する一連のFaceletsページを作成します。このチュートリアルの最後の<a href="#explore">アプリケーションの操作</a>の項には、このアプリケーションの理解を深め、IDEの習熟に役立つ様々な課題を用意しています(オプション)。</p>
<img alt="このページの内容は、NetBeans IDE 7.2、7.3、7.4および8.0に適用されます" class="stamp" src="../../../images_www/articles/73/netbeans-stamp-80-74-73.png" title="このページの内容は、NetBeans IDE 7.2、7.3、7.4および8.0に適用されます">
<h4>内容</h4>
<ul class="toc">
<li><a href="#createDB">データベースの作成</a></li>
<li><a href="#examineDB">データベース構造の確認</a></li>
<li><a href="#createProject">Webアプリケーション・プロジェクトの作成</a></li>
<li><a href="#generateEntity">データベースからのエンティティ・クラスの生成</a></li>
<li><a href="#jsfPagesEntityClasses">エンティティ・クラスからのJSFページの生成</a></li>
<li><a href="#explore">アプリケーションの操作</a>
<ul>
<li><a href="#completedProject">完了したプロジェクトの確認</a></li>
<li><a href="#populateDB">SQLスクリプトを使用したデータベースの生成</a></li>
<li><a href="#editorSupport">Faceletsページでのエディタのサポートの確認</a></li>
<li><a href="#dbIntegrity">フィールド検証を使用したデータベース整合性の確認</a></li>
<li><a href="#editEntity">エンティティ・クラスの編集</a></li>
</ul></li>
<li><a href="#troubleshooting">トラブルシューティング</a></li>
<li><a href="#seeAlso">関連項目</a></li>
</ul>
<p id="requiredSoftware">このチュートリアルを完了するには、次のソフトウェアとリソースが必要です。</p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">ソフトウェアまたはリソース</th>
<th class="tblheader" scope="col">必須バージョン</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バンドル版</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または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">または</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>注意: </strong></p>
<div class="indent">
<ul>
<li>NetBeans IDEのJava EEバンドル版には、このチュートリアルに必要な、Java EE準拠サーバーのGlassFishサーバーも含まれています。</li>
<li>このチュートリアルのソリューション・プロジェクトを入手するには、<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FConsultingAgencyJSF20.zip">ConsultingAgencyJSF20.zip</a>をダウンロードしてください。</li>
</ul>
</div>
<br>
<h2 id="createDB">データベースの作成</h2>
<p>このチュートリアルでは、<code>consult</code>という名前のコンサルティング・エージェンシ・データベースを使用します。このデータベースはIDEのインストールに含まれないため、このチュートリアルを開始する前に、まずデータベースを作成する必要があります。</p>
<p><code>consult</code>データベースは、様々なデータベース構造を処理するIDEサポートの幅広さを示すことを目的として設計されました。したがって、推奨されるデータベース設計の一例やベスト・プラクティスを示すものではありません。かわりに、データベース設計に使用できる関連機能の多くを取り入れようとしています。たとえば、<code>consult</code>データベースには、すべての関係タイプ、複合主キー、および多数の異なるデータ型が含まれています。データベース構造の詳しい概要については、このページの後に出てくる表を参照してください。</p>
<p><strong class="notes">注意: </strong></p>
<ul>
<li>このチュートリアルではMySQLデータベース・サーバーを使用しますが、JavaDBデータベース・サーバーを使用してチュートリアルを完了することもできます。JavaDBでデータベースを作成するには、<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fjavadb-consult.zip">javadb-consult.zip</a>アーカイブをダウンロードして抽出します。このアーカイブには、<code>consult</code>データベースを作成、ドロップおよび生成するためのSQLスクリプトが含まれています。</li>
<li>MySQLを操作するためのIDEの構成については、<a href="../ide/mysql.html">MySQLデータベースへの接続</a>のチュートリアルを参照してください。</li>
<li>JavaDBを操作するIDEの構成については、<a href="../ide/java-db.html">Java DB (Derby)データベースの操作</a>のチュートリアルを参照してください。</li>
</ul>
<div class="feedback-box float-left" style="width: 678px; margin: 0 0 10px 10px">
<p><strong class="alert">MySQLとGlassFishの組合せ:</strong></p>
<p>MySQLを使用する場合で、GlassFish v3またはOpen Source Edition 3.0.1を使用するときは、データベースがパスワードで保護されていることを確認する必要があります。(詳細は、GlassFishの<a href="https://java.net/jira/browse/GLASSFISH-12221" target="_blank">問題12221</a>を参照してください。)パスワードが設定されていないデフォルトのMySQL<code>root</code>アカウントを使用している場合は、コマンド行プロンプトからパスワードを設定できます。<br><br>たとえば、パスワードを<code><em>nbuser</em></code>に設定するには、コマンド行プロンプトで次のコマンドを入力します。</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><code>mysql: command not found</code>」というエラーが表示される場合は、<code>mysql</code>コマンドが<code>PATH</code>環境変数に追加されていません。かわりにMySQLのインストール・ディレクトリの<code>bin</code>ディレクトリのフル・パスを入力することで、コマンドをコールできます。たとえば、<code>mysql</code>コマンドがコンピュータ上の<code>/usr/local/mysql/bin</code>にある場合は、次のように入力します。</p>
<pre class="examplecode" style="width: 658px;">shell> /usr/local/mysql/bin/mysql -u root</pre>
<p>詳細は、MySQL公式リファレンス・マニュアルの以下を参照してください。</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/default-privileges.html" target="_blank">初期MySQLアカウントの保護</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/invoking-programs.html" target="_blank">4.2.1. MySQLプログラムの起動</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/setting-environment-variables.html" target="_blank">4.2.4. 環境変数の設定</a></li>
</ul>
</div>
<br style="clear: both;"/>
<br>
<p>次の手順を実行してデータベースを作成し、IDEからそのデータベースに接続します。</p>
<ol style="margin-top:0">
<li><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fmysql-consult.zip">mysql-consult.zip</a>をダウンロードし、アーカイブをローカル・システムに抽出します。アーカイブを抽出すると、データベースを作成および生成するためのSQLスクリプトが表示されます。このアーカイブには、ドロップする表のためのスクリプトも含まれています。</li>
<li>「サービス」ウィンドウで「データベース」ノードを展開し、「MySQL」ノードを右クリックして「サーバーを起動」を選択します。</li>
<li>「MySQLサーバー」ノードを右クリックし、「データベースを作成」を選択します。</li>
<li>「MySQLデータベースの作成」ダイアログでデータベース名として「<strong>consult</strong>」と入力します。「OK」をクリックします。「データベース」ノードの下に新しいノードが表示されます(<code>jdbc:mysql://localhost:3306/consult [デフォルト・スキーマのroot]</code>)。</li>
<li>新しいノードを右クリックし、「接続」を選択します。</li>
<li>メイン・メニューから「ファイル」>「ファイルを開く」を選択し、抽出したファイル<code>mysql_create_consult.sql</code>に移動します。「開く」をクリックします。ファイルがSQLエディタで自動的に開きます。<br> <img alt="SQLエディタのスクリーンショット" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/run-sql-script.png" title="IDEのエディタ内でSQLファイルを開く"></li>
<li>SQLエディタ・ツールバーの「接続」ドロップダウン・リストで<code>consult</code>データベースが選択されていることを確認し、「SQLの実行」(<img alt="「SQLの実行」ボタン" src="../../../images_www/articles/72/web/jsf20-crud/run-sql-btn.png">)ボタンをクリックします。
<p>「SQLの実行」をクリックすると、「出力」ウィンドウに次の出力が表示されます。</p>
<img alt="「出力」ウィンドウのスクリーンショット" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/run-sql-output.png" title="SQL実行時の情報が表示された「出力」ウィンドウ"></li>
</ol>
<br>
<h2 id="examineDB">データベース構造の確認</h2>
<p>表が正しく作成されたかどうかを確認するには、データベース接続ノードの下の「表」ノードを展開します。表のノードを展開すると、表の列、索引および外部キーを確認できます。列を右クリックして「プロパティ」を選択すると、その列に関する追加情報が表示されます。</p>
<div class="indent">
<img alt="「サービス」ウィンドウのスクリーンショット" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/services-window-tables.png" title="データベース接続、表、表の列、索引および外部キーが表示された「サービス」ウィンドウ">
</div>
<p class="notes"><strong>注意:</strong> 「表」ノードの下に表が表示されない場合は、「表」ノードを右クリックし、「リフレッシュ」を選択します。</p>
<p><code>consult</code>データベースの構造を見ると、様々な関係と様々な型のフィールドを含む表がデータベースにあることがわかります。データベースからエンティティ・クラスを作成するときは、フィールドの型ごとに適したコードが自動的に生成されます。</p>
<img alt="consultデータベースのエンティティ関係図" class="margin-around b-all" id="er-diagram" src="../../../images_www/articles/72/web/jsf20-crud/diagram_consult.png" title="consultデータベースのエンティティ関係図">
<p>次の表では、<code>consult</code>データベース内の表について説明します。</p>
<table class="indent" style="width: 744px">
<tr>
<th class="tblheader" scope="col">データベース表</th>
<th class="tblheader" scope="col">説明</th>
<th class="tblheader" scope="col">設計の特徴</th>
</tr>
<tr>
<td class="tbltd1">CLIENT</td>
<td class="tbltd0">コンサルティング・エージェンシのクライアント</td>
<td class="tbltd0">生成されない複合主キー(フィールドは外部キーを構成しない)</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT</td>
<td class="tbltd0">クライアントが契約に基づいて雇うことができる、コンサルティング・エージェンシの従業員</td>
<td class="tbltd0">LONG VARCHAR型のresumeフィールドを含む</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT_STATUS</td>
<td class="tbltd0">コンサルティング・エージェンシでのコンサルタントのステータス(「Active」や「Inactive」などのステータスが考えられる)</td>
<td class="tbltd0">生成されないCHAR型の主キー</td>
</tr>
<tr>
<td class="tbltd1">RECRUITER</td>
<td class="tbltd0">クライアントとコンサルタントのやり取りを担当する、コンサルティング・エージェンシの従業員</td>
<td class="tbltd0">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1">PROJECT</td>
<td class="tbltd0">クライアントがコンサルティング・エージェンシのコンサルタントを要員として充てるプロジェクト</td>
<td class="tbltd0">CLIENT表に対する外部キーを構成する2つのフィールドを含む、生成されない複合主キー</td>
</tr>
<tr>
<td class="tbltd1">BILLABLE</td>
<td class="tbltd0">コンサルタントがプロジェクトの任務に費やし、コンサルティング・エージェンシが関連クライアントに対して請求する時間数</td>
<td class="tbltd0">CLOB型のartifactフィールドを含む</td>
</tr>
<tr>
<td class="tbltd1">ADDRESS</td>
<td class="tbltd0">クライアントの請求先住所</td>
<td class="tbltd0">&nbsp;</td>
</tr>
<tr>
<td class="tbltd1">PROJECT_CONSULTANT</td>
<td class="tbltd0">コンサルタントが現在割り当てられているプロジェクトを示す結合表</td>
<td class="tbltd0">PROJECTとCONSULTANTとを相互参照し、PROJECTには複合主キーがある</td>
</tr>
</table>
<br>
<p><code>consult</code>データベースには、様々な関係が含まれています。エンティティ・クラスをデータベースから作成する場合、列のSQL型に基づいて、適切なJava型のプロパティが自動的に生成されます。次の表では、<code>consult</code>データベースのエンティティ関係を説明します。逆方向の関係は示していません。</p>
<table id="relationships" class="indent" style="width: 744px">
<tr>
<th class="tblheader" scope="col">エンティティ</th>
<th class="tblheader" scope="col">関連するエンティティ</th>
<th class="tblheader" scope="col">関係の情報</th>
<th class="tblheader" scope="col">説明</th>
</tr>
<tr>
<td class="tbltd1">CLIENT</td>
<td class="tbltd0">RECRUITER</td>
<td class="tbltd0">手動編集ありでnull可能な1対1の関係、編集なしでnull可能な1対多の関係</td>
<td class="tbltd0">CLIENTには多数のRECRUITERがあり、RECRUITERには0または1つのCLIENTがあります(手動で編集されていない場合)</td>
</tr>
<tr>
<td class="tbltd1">CLIENT</td>
<td class="tbltd0">ADDRESS</td>
<td class="tbltd0">null可能ではない1対1の関係</td>
<td class="tbltd0">CLIENTには1つのADDRESSがあり、ADDRESSには0または1つのCLIENTがあります</td>
</tr>
<tr>
<td class="tbltd1">CLIENT</td>
<td class="tbltd0">PROJECT</td>
<td class="tbltd0">null可能ではない1対多の関係、Projectエンティティのclientフィールドの値はProjectの主キーの一部</td>
<td class="tbltd0">CLIENTには多数のPROJECTがあり、PROJECTには1つのCLIENTがあります</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT</td>
<td class="tbltd0">PROJECT</td>
<td class="tbltd0">多対多</td>
<td class="tbltd0">CONSULTANTには複数のPROJECTがあり、PROJECTには多数のCONSULTANTがあります</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT</td>
<td class="tbltd0">BILLABLE</td>
<td class="tbltd0">null可能ではない1対多の関係</td>
<td class="tbltd0">CONSULTANTには多数のBILLABLEがあり、BILLABLEには1つのCONSULTANTがあります</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT_STATUS</td>
<td class="tbltd0">CONSULTANT</td>
<td class="tbltd0">null可能ではない1対多の関係</td>
<td class="tbltd0">CONSULTANT_STATUSには多数のCONSULTANTがあり、CONSULTANTには1つのCONSULTANT_STATUSがあります</td>
</tr>
<tr>
<td class="tbltd1">CONSULTANT</td>
<td class="tbltd0">RECRUITER</td>
<td class="tbltd0">null可能な1対多の関係</td>
<td class="tbltd0">CONSULTANTには0または1つのRECRUITERがあり、RECRUITERには多数のCONSULTANTがあります</td>
</tr>
<tr>
<td class="tbltd1">BILLABLE</td>
<td class="tbltd0">PROJECT</td>
<td class="tbltd0">null可能ではない1対多の関係</td>
<td class="tbltd0">BILLABLEには1つのPROJECTがあり、PROJECTには多数のBILLABLEがあります</td>
</tr>
</table>
<p>データベースが作成されたので、次にWebアプリケーションを作成し、データベースからのエンティティ・クラス・ウィザードを使用して、データベースの表に基づいてエンティティ・クラスを生成できます。</p>
<h2 id="createProject">Webアプリケーション・プロジェクトの作成</h2>
<p>この課題では、Webプロジェクトを作成し、JavaServer Facesフレームワークをプロジェクトに追加します。プロジェクトを作成するときは、新規プロジェクト・ウィザードの「フレームワーク」パネルで「JavaServer Faces」を選択します。</p>
<ol>
<li>メイン・メニューから「ファイル」>「新規プロジェクト」([Ctrl]-[Shift]-[N]、Macの場合は[&#8984]-[Shift]-[N])を選択します。</li>
<li>「Java Web」カテゴリから「Webアプリケーション」を選択します。「次」をクリックします。</li>
<li>プロジェクト名として「<code>ConsultingAgency</code>」と入力し、プロジェクトの場所を設定します。「次」をクリックします。</li>
<li>サーバーを「GlassFish」に設定し、「Java EEバージョン」を「Java EE 6 Web」または「Java EE 7 Web」に設定します。「次」をクリックします。</li>
<li>「フレームワーク」パネルで「JavaServer Faces」オプションを選択します。「終了」をクリックします。</li>
</ol>
<p>「終了」をクリックすると、IDEはWebアプリケーション・プロジェクトを生成し、<code>index.xhtml</code>がエディタに表示されます。</p>
<h2 id="generateEntity">データベースからのエンティティ・クラスの生成</h2>
<p>IDEでデータベースに接続した後、データベースからのエンティティ・クラス・ウィザードを使用して、データベース内の表に基づいてすばやくエンティティ・クラスを生成できます。IDEでは、選択した各表のエンティティ・クラスを生成でき、関連する表に必要なエンティティ・クラスを生成することもできます。</p>
<ol>
<li>「プロジェクト」ウィンドウで「<code>ConsultingAgency</code>」プロジェクト・ノードを右クリックし、「新規」>「データベースからのエンティティ・クラス」を選択します。このオプションがリストにない場合は「その他」を選択します。次に、ファイル・ウィザードで「持続性」カテゴリを選択し、「データベースからのエンティティ・クラス」を選択します。</li>
<li>「データ・ソース」ドロップダウン・リストから「新しいデータ・ソース」を選択して「データ・ソースを作成」ダイアログを開きます。</li>
<li>「JNDI名」に「<code>jdbc/consult</code>」と入力し、「データベース接続」に「<code>jdbc:mysql://localhost:3306/consult</code>」接続を選択します。<br> <img alt="「データソースを作成」ダイアログ・ボックス" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/create-datasource.png" title="データソースを作成するためのJNDI名およびデータベース接続の指定"></li>
<li>「OK」をクリックしてダイアログ・ボックスを閉じ、ウィザードに戻ります。<code>consult</code>データベース内の表が「使用可能な表」リスト・ボックスに表示されます。</li>
<li>「すべてを追加」ボタンをクリックし、データベースに格納されているすべての表を選択します。「次」をクリックします。<br> <img alt="データベースからの新規エンティティ・ウィザード" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/new-entities-wizard.png"></li>
<li>「パッケージ」名に「<code>jpa.entities</code>」と入力します。 </li>
<li>名前付き問合せを生成するためのチェックボックスと持続性ユニットを作成するためのチェックボックスが選択されていることを確認します。「終了」をクリックします。</li>
</ol>
<p>「終了」をクリックすると、IDEは、プロジェクトの<code>jpa.entities</code>パッケージにエンティティ・クラスを生成します。</p>
<p>ウィザードを使用してデータベースからエンティティ・クラスを作成するとき、IDEでデータベース表間の関係が確認されます。「プロジェクト」ウィンドウで「<code>jpa.entities</code>」パッケージ・ノードを展開すると、IDEによって<code>PROJECT_CONSULTANT</code>表を除くすべての表のエンティティ・クラスを生成されていることがわかります。<code>PROJECT_CONSULTANT</code>のエンティティ・クラスが作成されなかった理由は、この表が結合表であるためです。</p>
<div class="indent">
<img alt="「プロジェクト」ウィンドウのスクリーンショット" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/projects-window-entities.png" title="生成されたエンティティ・クラスが表示された「プロジェクト」ウィンドウのスクリーンショット">
</div>
<p>また、IDEは複合主キーを持つ<code>CLIENT</code><code>PROJECT</code>の各表に2つの追加クラスを生成します。これらの表の主キー・クラス(<code>ClientPK.java</code><code>ProjectPK.java</code>)の名前には、<code>PK</code>が付加されています。</p>
<p>エンティティ・クラスに生成されたコードを見ると、エンティティ・クラスの自動生成IDフィールドに<code>@GeneratedValue</code>注釈が、一部のフィールドに<code>@Basic(optional="false")</code>注釈がウィザードによって追加されていることがわかります。エンティティからのJSFページ・クラス・ウィザードでは、<code>@Basic(optional="false")</code>注釈に基づき、これらのフィールドでnull可能ではない列の違反を防止するためのチェック機能を含むコードを生成できます。</p>
<br>
<h2 id="jsfPagesEntityClasses">エンティティ・クラスからのJSFページの生成</h2>
<p>エンティティ・クラスが作成されたので、次にデータを表示および変更するためのWebインタフェースを作成できます。ここでは、エンティティからのJSFページ・クラス・ウィザードを使用して、JavaServer Facesページを生成します。ウィザードで生成されるコードは、エンティティ・クラス内に格納された持続性注釈に基づいて生成されます。</p>
<p>ウィザードでは、エンティティ・クラスごとに次のファイルが生成されます。</p>
<ul>
<li><tt>AbstractFacade.java</tt>を拡張するステートレス・セッションBean</li>
<li>JSFセッション・スコープ指定管理対象Bean</li>
<li>CRUD機能のための4つのFaceletsファイル(<code>Create.xhtml</code><code>Edit.xhtml</code><code>List.xhtml</code>、および<code>View.xhtml</code>)を格納するディレクトリ</li>
</ul>
<p>ウィザードでは、次のファイルも生成します。</p>
<ul>
<li>エンティティ・インスタンスの作成、取得、変更および除去のためのビジネス・ロジックを含む<tt>AbstractFacade.java</tt>クラス</li>
<li>JSF管理対象Bean (<code>JsfUtil</code><code>PaginationHelper</code>)に使用されるユーティリティ・クラス</li>
<li>ローカライズされたメッセージのプロパティ・バンドル、およびプロジェクトのFaces構成ファイル内(このファイルがない場合、<code>faces-config.xml</code>ファイルが作成される)の対応するエントリ</li>
<li>レンダリングされるコンポーネントのデフォルトのスタイル・シートおよびFaceletsテンプレート・ファイルを含む、補助Webファイル</li>
</ul>
<p>JSFページを生成するには:</p>
<ol>
<li>「プロジェクト」ウィンドウで、プロジェクト・ノードを右クリックし、「新規」>「エンティティからのJSFページ・クラス」を選択してウィザードを開始します。このオプションがリストにない場合は「その他」を選択します。次に、ファイル・ウィザードで、「JavaServer Faces」カテゴリを選択し、「エンティティからのJSFページ・クラス」を選択します。
<p>
「利用可能なエンティティ・クラス」ボックスに、プロジェクトに含まれる7つのエンティティ・クラスが一覧表示されます。このボックスには、組込み可能なクラス(<code>ClientPK.java</code><code>ProjectPK.java</code>)は一覧表示されません。</p></li>
<li>「すべてを追加」をクリックして、すべてのクラスを「選択されているエンティティ・クラス」ボックスに移動します。<br><img alt="「新規エンティティからのJSFページ・クラス」ウィザード" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/newjsf-wizard.png" title="プロジェクトに含まれるすべてのエンティティ・クラスが表示された「新規エンティティからのJSFページ・クラス」ウィザード"><br>「次」をクリックします。</li>
<li>ウィザードのステップ3の「生成されたJSFページとクラス」で、「JPAセッションBeanパッケージ」に「<code>jpa.session</code>」と入力します。</li>
<li>「JSFクラス・パッケージ」に「<code>jsf</code>」と入力します。</li>
<li>「ローカリゼーション・バンドル名」フィールドに「<code>/resources/Bundle</code>」と入力します。これにより、<code>resources</code>という名前のパッケージが生成され、これに<code>Bundle.properties</code>ファイルが属します。ここを空白のままにした場合、プロパティ・バンドルはプロジェクトのデフォルトのパッケージ内に作成されます。<br> <img alt="「新規エンティティからのJSFページ・クラス」ウィザードのステップ3" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/newjsf-wizard2.png" title="生成されたファイルに対するパッケージ名とフォルダ名の指定">
<p class="tips">IDEをプロジェクトの規則により適応させるために、ウィザードで生成した任意のファイルをカスタマイズできます。「テンプレートのカスタマイズ」リンクをクリックし、ウィザードで使用されるファイル・テンプレートを変更します。<br><img alt="「テンプレートをカスタマイズ」ドロップダウン・リスト" class="margin-around" src="../../../images_www/articles/72/web/jsf20-crud/customize-template.png" title="ウィザードで生成されたファイルの「テンプレートをカスタマイズ」"><br>一般に、IDEで管理されるすべてのテンプレートには、「テンプレート・マネージャ」(「ツール」>「テンプレート」)を使用してアクセスし、変更を加えることができます。</p></li>
<li>「終了」をクリックします。ステートレス・セッションBeanが<code>jpa.session</code>パッケージ内に生成され、JSFセッション・スコープ指定管理対象Beanが<code>jsf</code>パッケージ内に生成されます。各ステートレス・セッションBeanは、対応するエンティティ・クラスの操作を処理します。これには、Java Persistence APIを経由したエンティティ・クラスのインスタンスの作成、編集および破棄が含まれます。各JSF管理対象Beanは、<code>javax.faces.convert.Converter</code>インタフェースを実装し、対応するエンティティ・クラスのインスタンスと<code>String</code>型オブジェクトの間の変換作業を行います。</li>
</ol>
<p>「Webページ」ノードを展開すると、エンティティ・クラスごとにフォルダが生成されたことがわかります。各フォルダには、<code>Create.xhtml</code><code>Edit.xhtml</code><code>List.xhtml</code>および<code>View.xhtml</code>ファイルが格納されます。<code>index.xhtml</code>ファイルも変更され、各<code>List.xhtml</code>ページへのリンクが挿入されます。</p>
<div class="indent">
<img alt="「プロジェクト」ウィンドウの「Webページ」ディレクトリのスクリーンショット" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/projects-jsfpages.png" title="ウィザードによって生成された、各エンティティの「Facelets」ページ">
</div>
<p>各JSF管理対象Beanは、4つの対応するFaceletsファイルに固有のもので、適切なセッションBean内のメソッドを呼び出すコードが格納されます。</p>
<p><code>resources</code>」フォルダ・ノードを展開し、ウィザードで生成されたデフォルトの<code>jsfcrud.css</code>スタイル・シートを検索します。アプリケーションの開始ページ(<code>index.xhtml</code>)またはFaceletsテンプレート・ファイル(<code>template.xhtml</code>)をエディタで開くと、次のようなスタイル・シートへの参照が表示されます。</p>
<div class="indent">
<pre class="examplecode">&lt;h:outputStylesheet name=&quot;css/jsfcrud.css&quot;/&gt;</pre>
</div>
<p>Faceletsテンプレート・ファイルは、各エンティティ・クラスの4つの各Faceletsファイルで使用されます。</p>
<p>「ソース・パッケージ」ノードを展開すると、セッションBeans、JSF管理対象Bean、ユーティリティ・クラス、およびウィザードで生成されたプロパティ・バンドルが確認できます。</p>
<div class="indent">
<img alt="「プロジェクト」ウィンドウの「ソース・パッケージ」ディレクトリのスクリーンショット" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/projects-generated-classes70.png" title="ウィザードによって生成されたクラスが表示された「プロジェクト」ウィンドウの「ソース・パッケージ」ディレクトリのスクリーンショット">
</div>
<p>ウィザードでは、プロパティ・バンドルの場所を登録するためのFaces構成ファイル(<code>faces-config.xml</code>)も生成されます。「構成ファイル」ノードを展開し、<code>faces-config.xml</code>をXMLエディタで開くと、次のエントリが格納されていることがわかります。</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>また、新規<code>resources</code>パッケージを展開すると、クライアントのデフォルト言語のメッセージが格納されている<code>Bundle.properties</code>ファイルがあります。このメッセージは、エンティティ・クラス・プロパティから派生します。</p>
<p class="tips">新規プロパティ・バンドルを追加するには、<code>Bundle.properties</code>ファイルを右クリックし、「カスタマイズ」を選択します。「カスタマイザ」ダイアログで、新しいロケールをアプリケーションに追加できます。</p>
<br>
<h2 id="explore">アプリケーションの操作</h2>
<p>これで、エンティティ・クラス、エンティティ・クラスを制御するためのEJBセッションBeans、データベースを表示および編集するためのJSFによるフロント・エンドがプロジェクトに組み込まれたので、プロジェクトを実行して結果を確認してみます。</p>
<p>次に、このアプリケーションとIDEで提供される機能の習熟に役立つ、一連の短い課題を示します(オプション)。</p>
<ul>
<li><a href="#completedProject">完了したプロジェクトの確認</a></li>
<li><a href="#populateDB">SQLスクリプトを使用したデータベースの生成</a></li>
<li><a href="#editorSupport">Faceletsページでのエディタのサポートの確認</a></li>
<li><a href="#dbIntegrity">フィールド検証を使用したデータベース整合性の確認</a></li>
<li><a href="#editEntity">エンティティ・クラスの編集</a></li>
</ul>
<div class="indent">
<h3 id="completedProject">完了したプロジェクトの確認</h3>
<ol>
<li>プロジェクトを実行するには、「プロジェクト」ウィンドウでプロジェクトのノードを右クリックして「実行」を選択するか、メイン・ツールバーで「プロジェクトの実行」(<img alt="「プロジェクトの実行」ボタン" src="../../../images_www/articles/72/web/jsf20-crud/run-project-btn.png">)ボタンをクリックします。
<p>
アプリケーションの開始ページが表示されると、リンク・リストが表示され、これらを使用して各データベース表に格納されたエントリを表示できます。
</p>
<img alt="ブラウザ内のConsultingAgencyの開始ページ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/welcome-page-links.png" title="各表のデータベースの内容を表示するためのリンク">
<p>
これらのリンクは、エンティティからのJSFページ・クラス・ウィザードを完了したら、開始ページ(<code>index.xhtml</code>)に追加されます。これらはコンサルティング・エージェンシ・データベース上でCRUD機能を提供するFaceletsページへのエントリ・ポイントとして提供されます。</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><code>Show All Consultant Items</code>」リンクをクリックします。前出のコードを参照すると、ターゲット・ページが<code>/consultant/List.xhtml</code>であることがわかります。(JSF 2.xでは、ファイル拡張子は暗黙のナビゲーションによって推定されます。)<br><img alt="コンサルタント・ページ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/empty-consultants-list.png" title="コンサルタント表は現在空"><br>このデータベースには、現在サンプル・データが含まれていません。「<code>Create New Consultant</code>」リンクをクリックし、表示されるWebフォームを使用することでデータを手動で追加できます。これにより、<code>/consultant/Create.xhtml</code>ページの表示がトリガーされます。また、SQLスクリプトをIDEで実行し、サンプル・データを含む表を生成することもできます。次の項では、両方の選択肢を示します。</li>
</ol>
<p>indexリンクをクリックすると、開始ページ内に一覧表示されたリンクに戻ることができます。これらのリンクには、各データベース表が保持するデータのビューと、各エンティティ・フォルダの<code>List.xhtml</code>ファイルを表示するためのトリガーがあります。後述の説明にあるように、データを表に追加した後、各エントリに他のリンクが表示され、単一の表レコードのデータを表示(<code>View.xhtml</code>)、編集(<code>Edit.xhmtl</code>)および破棄できます。</p>
<p class="notes"><strong>注意:</strong>アプリケーションのデプロイに失敗した場合は、下の<a href="#troubleshooting">「トラブルシューティング」セクション</a>を参照してください。(<a href="mysql-webapp.html#troubleshoot">MySQLデータベースを使用した単純なWebアプリケーションの作成</a>の「トラブルシューティング」セクションも参照してください。)</p>
<h3 id="populateDB">SQLスクリプトを使用したデータベースの生成</h3>
<p>提供されたスクリプトを実行します。このスクリプトにより、データベース表のサンプル・データが生成されます。このスクリプト(<code>mysql_insert_data_consult.sql</code>)はコンサルティング・エージェンシ・データベースのZIPファイルに格納されており、<a href="#requiredSoftware">必要なソフトウェアの表</a>からダウンロードできます。</p>
<p>操作するデータベース・サーバー(MySQLまたはJavaDB)に応じて、提供されているスクリプトを実行できます。このスクリプトにより、データベース表のサンプル・データが生成されます。MySQLの場合は、<code>mysql_insert_data_consult.sql</code>スクリプトになります。JavaDBの場合は、<code>javadb_insert_data_consult.sql</code>スクリプトになります。どちらのスクリプトも、<a href="#requiredSoftware">必要なソフトウェアの表</a>からダウンロードできるそれぞれのアーカイブの中に含まれています。</p>
<ol>
<li>メイン・メニューから「ファイル」>「ファイルを開く」を選択し、コンピュータ上のスクリプトの場所に移動します。「開く」をクリックします。ファイルがIDEのSQLエディタで自動的に開きます。</li>
<li>SQLエディタのツールバーの「接続」ドロップダウン・リストで<code>consult</code>データベースが選択されていることを確認します。<br> <img alt="SQLエディタとデータ挿入スクリプトのスクリーンショット" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/run-sql-insert.png" title="IDEのSQLエディタ内でスクリプトを開く">
<p>
エディタ内を右クリックして「文の実行」を選択するか、「SQLの実行」(<img alt="「SQLの実行」ボタン" src="../../../images_www/articles/72/web/jsf20-crud/run-sql-btn.png">)ボタンをクリックします。スクリプトの実行結果は「出力」ウィンドウで確認できます。</p></li>
<li>GlassFishサーバーを再起動します。<code>consult</code>データベースに含まれる新しいデータをサーバーが再ロードしたり、キャッシュに保存できるようにするには、このステップが必要となります。そのためには、「出力」ウィンドウのGlassFishサーバーのタブ(GlassFishサーバーのタブにはサーバーのログが表示される)をクリックし、左マージンにある「サーバーを再起動」(<img alt="「サーバーを再起動」ボタン" src="../../../images_www/articles/72/web/jsf20-crud/glassfish-restart.png">)ボタンをクリックします。サーバーが停止し、再起動します。</li>
<li>プロジェクトを再度実行し、「<code>Show All Consultant Items</code>」リンクをクリックします。リストが空でなくなっていることがわかります。<br><a href="../../../images_www/articles/72/web/jsf20-crud/consultants-list.png" id="consultantsList" rel="lytebox" title="コンサルタント表に含まれているエントリを表示するFaceletsページ"><img alt="表のエントリが表示されたコンサルタント・ページ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/consultants-list-small.png"></a>
<div class="feedback-box float-left" style="width: 683px;">
<h3>NetBeansのデータベース・サポート</h3>
<p>IDEのデータベース表ビューアを使用すると、管理されている表データをデータベース内で直接表示および変更できます。たとえば、<code>consultant</code>表を「サービス」ウィンドウで右クリックし、「データを表示」を選択します。</p>
<img alt="「サービス」ウィンドウ - データベース表の右クリック・メニュー" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/view-data.png" title="データベース表の右クリック・メニューによる「データを表示」の選択">
<p>アクションの実行に使用されるSQL問合せがエディタの上部に表示され、表のグラフィカル・ビューが下部に表示されます。</p>
<a href="../../../images_www/articles/72/web/jsf20-crud/view-data-table.png" rel="lytebox" title="データベース表のグラフィカル・ビューを使用した、表のデータの表示と変更"> <img alt="データベースのデータが表示されたSQLエディタ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/view-data-table-small.png"></a>
<p>表のセルの内側をダブルクリックして、データへのインライン変更を実行します。「レコードをコミット」(<img alt="「レコードをコミット」アイコン" src="../../../images_www/articles/72/web/jsf20-crud/commit-records-icon.png">)アイコンをクリックし、変更内容をデータベースにコミットします。</p>
<p>
グラフィカル・ビューには多数の機能が用意されています。詳細は、<a href="../../docs/ide/database-improvements-screencast.html">Database Support in NetBeans IDEでのデータベースのサポート</a>を参照してください。</p>
</div>
<br style="clear: both;"/></li>
</ol>
<h3 id="editorSupport">Faceletsページでのエディタのサポートの確認</h3>
<ol>
<li>エディタで<code>/consultant/List.xhtml</code>ページを開きます。レンダリングするFaceletsの<code>template.xhtml</code>ファイルに依存するページが8行目に示されます。
<pre class="examplecode">&lt;ui:composition template=&quot;/template.xhtml&quot;&gt;</pre>
<p class="tips">行番号を表示するには、エディタの左マージンを右クリックし、「行番号を表示」を選択します。</p></li>
<li>IDEの「ファイル」ダイアログを使用し、<code>template.xhtml</code>を開きます。[Alt]-[Shift]-[O] (Macの場合は[Ctrl]-[Shift]-[O])を押して、「<code>template</code>」と入力します。<br> <img alt="「ファイルに移動」ダイアログ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/go-to-file.png" title="「ファイルに移動」ダイアログを使用してプロジェクト・ファイルを速やかに開く">
<p>「OK」をクリックするか、[Enter]を押します。</p></li>
<li>このテンプレートは、他のファイルからタイトルと本体に内容を挿入するための<code>&lt;ui:insert></code>タグを適用します。<code>&lt;ui:insert></code>タグの上にカーソルを置いて、[Ctrl]-[Space]を押し、ドキュメント・ポップアップ・ウィンドウを呼び出します。<br> <img alt="エディタに表示されたドキュメントのポップアップ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/doc-popup.png" title="[Ctrl]-[Space]の押下による、Faceletsタグでのドキュメント・ポップアップの呼出し">
<p>JSFタグおよびその属性上で[Ctrl]-[Space]を押すと、ドキュメント・ポップアップを呼出しできます。表示されるドキュメントは、公式の<a href="http://javaserverfaces.java.net/nonav/docs/2.1/vdldocs/facelets/index.html">JSFタグ・ライブラリ・ドキュメント</a>で提供されている説明から取得したものです。</p></li>
<li><code>List.xhtml</code>ファイルに戻ります([Ctrl]-[Tab]を押します)。<code>&lt;ui:define></code>タグは、テンプレートのタイトルと本体に適用する内容を定義するために使用されます。このパターンは、各エンティティ・クラスに対して生成される4つのFaceletsファイル(<code>Create.xhtml</code><code>Edit.xhtml</code><code>List.xhtml</code>、および<code>View.xhtml</code>)すべてに使用されます。</li>
<li><code>Bundle.properties</code>ファイルに含まれる、ローカライズされたメッセージに使用される任意のEL式にカーソルを置きます。[Ctrl]-[Space]を押してローカライズされたメッセージを表示します。<br><a href="../../../images_www/articles/72/web/jsf20-crud/localized-messages.png" rel="lytebox" title="エディタのコード補完サポートを使用した、ローカライズされたメッセージの表示"><img alt="プロパティ・バンドルからのメッセージのコード補完ポップアップ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/localized-messages-small.png"></a>
<p>前出のイメージに、「<code>List</code>」を解決するEL式が表示されています。これは、テンプレートのタイトルに適用され、ブラウザにレンダリングされるページから確認できます。</p></li>
<li>ファイルの最下部にスクロールし、92行目にある「<code>Create New Consultant</code>」リンクのコードに移動します。この内容は次のとおりです。
<pre class="examplecode">
&lt;h:commandLink action=&quot;#{consultantController.prepareCreate}&quot; value=&quot;#{bundle.ListConsultantCreateLink}&quot;/&gt;</pre></li>
<li><code>commandLink</code><code>action</code>属性の上で[Ctrl]-[Space]を押し、ドキュメント・ポップアップを呼び出します。<br><br><code>action</code>属性は、ブラウザ内でリンクがクリックされた際のリクエストを処理するメソッドを示します。次のドキュメントが表示されます。<br><br>
<div class="indent" style="width:680px">
<em>ユーザーがこのコンポーネントをアクティブ化したときに起動するアプリケーション・アクションを表すメソッド式。この式は、パラメータを取得せず、オブジェクト(論理的な結果を取得するためにコールされるtoString()オブジェクト)を返すpublicメソッドに評価される必要があり、このオブジェクトはこのアプリケーションのNavigationHandlerに渡されます。</em></div>
<br>つまり、<code>action</code>値は通常、<code>String</code>型として評価されるJSF管理対象Bean内のメソッドを参照します。この文字列は、リクエストを適切なビューに転送するため、JSFの<code>NavigationHandler</code>に使用されます。これは次の手順で確認します。</li>
<li>カーソルを<code>consultantController</code>の上に置き、[Ctrl]-[Space]を押します。エディタのコード補完で、<code>consultantController</code>がJSF管理対象Beanであることが示されます。<br> <img alt="エディタ内で呼び出されたコード補完" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/code-completion-managed-bean.png" title="JSF管理対象Beanに対して提供されるコード補完"></li>
<li>カーソルを<code>prepareCreate</code>に移動し、[Ctrl]-[Space]を押します。コード補完によって、<code>ConsultantController</code>管理対象Bean内に格納されたメソッドの一覧が表示されます。<br> <img alt="エディタ内で呼び出されたコード補完" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/code-completion-properties.png" title="クラス・メソッドに対して提供されるコード補完"></li>
<li>[Ctrl] (Macの場合は[&#8984])を押し、マウスを<code>prepareCreate</code>の上に移動します。リンクが形成され、このリンクを使用して<code>ConsultantController</code>管理対象Bean内の<code>prepareCreate()</code>メソッドに直接移動できます。<br> <img alt="エディタに表示されたリンク" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/editor-navigation.png" title="エディタのナビゲーションを使用した、ソース・コードへの速やかな移動"></li>
<li>リンクをクリックし、次に示す<code>prepareCreate()</code>メソッドを表示します。
<pre class="examplecode">
public String prepareCreate() {
current = new Consultant();
selectedItemIndex = -1;
return &quot;Create&quot;;
}</pre>
このメソッドは、<code>Create</code>を返します。<code>NavigationHandler</code>はバックグラウンドで情報を収集し、リクエストに対するレスポンスとして送信されるビューをターゲットとするパスに<code>Create</code>文字列を適用します(<code>/consultant/<strong>Create</strong>.xhtml</code>)。(JSF 2.xでは、ファイル拡張子は暗黙のナビゲーションによって推定されます。)</li>
</ol>
<h3 id="dbIntegrity">フィールド検証を使用したデータベース整合性の確認</h3>
<ol>
<li>ブラウザの<a href="#consultantsList">Consultants List</a>ページから、「<code>Create New Consultant</code>」リンクをクリックします。前の項で説明したように、これによって<code>/consultant/Create.xhtml</code>ページのレンダリングがトリガーされます。</li>
<li>次の詳細をフォームに入力します。ここでは<code>RecruiterId</code>フィールドと<code>StatusId</code>フィールドの両方を空白のままにします。<br><br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">フィールド</th>
<th class="tblheader" scope="col"></th>
</tr>
<tr>
<td class="tbltd1">ConsultantId</td>
<td class="tbltd1">2</td>
</tr>
<tr>
<td class="tbltd1">電子メール</td>
<td class="tbltd1">jack.smart@jsfcrudconsultants.com</td>
</tr>
<tr>
<td class="tbltd1">パスワード</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>「保存」をクリックします。これを実行すると、<code>StatusId</code>フィールドに検証エラーのフラグが表示されます。<br><img alt="サンプル・データが表示されたCreate New Consultantページ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/create-new-consultant.png" title="フォームへのサンプル・データの入力"><br>なぜこの状態になるのでしょうか。<a href="#er-diagram">コンサルティング・エージェンシ・データベースのエンティティの関係図</a>を再度考察するとわかります。前出の<a href="#relationships">リレーショナル表</a>にあるように、<code>CONSULTANT</code>表および<code>CONSULTANT_STATUS</code>表はnull可能ではない1対多の関係を共有しています。そのため、<code>CONSULTANT</code>表のすべてのエントリには、<code>CONSULTANT_STATUS</code>表内のエントリに対する参照が含まれている必要があります。これは、2つの表をリンクする<code>consultant_fk_consultant_status</code>外部キーによって示されています。
<p class="tips">表に保持されている外部キーは、「サービス」ウィンドウ([Ctrl]-[5]、Macの場合は[&#8984]-[5])で表の「外部キー」ノードを展開すると表示できます。</p>
<img alt="「サービス」ウィンドウ - consultant表の外部キー" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/consultant-fk.png" title="「サービス」ウィンドウでの外部キー属性の調査"></li>
<li>検証エラーを解決するには、「<code>StatusId</code>」ドロップダウン・リストから「<code>entity.ConsultantStatus[statusId=A]</code>」を選択します。<br><br><strong class="notes">注意:</strong> <code>RecruiterId</code>フィールドは空白のままでかまいません。<a href="#er-diagram">データベースのエンティティ関係図</a>に示すとおり、<code>CONSULTANT</code>表と<code>RECRUITER</code>表との間には、null可能な1対多の関係があります。これは、<code>CONSULTANT</code>内のエントリは<code>RECRUITER</code>エントリと関連付ける必要がないということです。</li>
<li>「保存」をクリックします。consultantのエントリが正常に保存されたことを示すメッセージが表示されます。「<code>Show All Consultant Items</code>」をクリックすると、表にリストされた新規エントリが表示されます。</li>
</ol>
<p>一般に、生成されたFaceletsページには、次のことが発生するユーザー入力に対してエラーを表示します。</p>
<ul>
<li>null可能ではない表のセルに対する空のフィールド。</li>
<li>主キーなどの変更できないデータの変更。</li>
<li>型が正しくないデータの挿入。</li>
<li>ユーザーのビューがデータベースと同期していないときのデータの変更。</li>
</ul>
<h3 id="editEntity">エンティティ・クラスの編集</h3>
<p>前の項で、ユーザーにとってわかりやすくない「<code>entity.ConsultantStatus[statusId=A]</code>」オプションを「<code>StatusId</code>」ドロップダウン・リストに表示する方法を確認しました。ドロップダウン・リストの各項目に表示されるテキストは、たとえばエンティティ・クラスの<code>toString()</code>メソッドがコールされることよって発生した、各<code>ConsultantStatus</code>エンティティに対する文字列表現であることがすでにおわかりでしょう。</p>
<p>この項では、締めくくりとして、エディタのコード補完、ドキュメント、およびナビゲーション・サポートを使用する方法を説明します。また、ユーザーにとってよりわかりやすいメッセージをドロップダウン・リストに表示する方法も示します。</p>
<ol>
<li id="markup">エディタで<code>/consultant/Create.xhtml</code>ファイルを開きます。これは、先ほどブラウザで表示した「Create New Consultant」フォームです。次に<strong>太字</strong>で示す、「<code>StatusId</code>」ドロップダウン・リストのコードまでスクロールします。
<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><code>&lt;f:selectItems></code>タグに適用される<code>value</code>を確認します。<code>value</code>属性は、ドロップダウン・リストの各項目に表示するテキストを決定します。<br><br><code>itemsAvailableSelectOne</code>上で[Ctrl]-[Space]を押します。エディタのコード補完に、<code>ConsultantStatusController</code><code>getItemsAvailableSelectOne()</code>メソッドが<code>SelectItem</code>オブジェクトの配列を返すことが示されます。<br> <img alt="エディタ内で呼び出されたコード補完" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/code-completion-returned-object.png" title="メソッドに対して返されるクラスが表示されたコード補完"></li>
<li>[Ctrl] (Macの場合は[&#8984])を押し、マウスを<code>itemsAvailableSelectOne</code>の上に移動します。リンクが形成され、このリンクを使用して<code>ConsultantStatus</code>エンティティのソース・コード内の<code>getItemsAvailableSelectOne()</code>メソッドに直接移動できます。リンクをクリックします。</li>
<li>メソッド署名内の<code>SelectItem[]</code>戻り値の上にカーソルを置き、[Ctrl]-[Space]を押してドキュメント・ポップアップを呼び出します。<br> <img alt="Javaクラス内で呼び出されたドキュメント・ポップアップ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/documentation-select-item.png" title="[Ctrl]-[Space]の押下によるドキュメント・サポートの呼出し">
<p class="tips">ドキュメント・ウィンドウの「Webブラウザ」(<img alt="「Webブラウザ」アイコン" src="../../../images_www/articles/72/web/jsf20-crud/web-browser-icon.png">)アイコンをクリックし、外部WebブラウザでJavadocを開きます。</p>
表示されるように、<code>SelectItem</code>クラスはJSFフレームワークに属しています。このドキュメントにあるように、<code>UISelectOne</code>コンポーネントは、前出の<a href="#markup">ステップ1</a>で調べたマークアップからの<code>&lt;h:selectOneMenu></code>タグによって表現されます。</li>
<li>[Ctrl] (Macの場合は[&#8984])を押し、マウスを<code>findAll()</code>の上に移動します。ポップアップが表示され、メソッド署名が示されます。<br><img alt="メソッド署名のポップアップ" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/method-signature.png" title="エディタでのメソッド署名のポップアップの表示"><br>ここで、<code>ejbFacade.findAll()</code><code>ConsultantStatus</code>オブジェクトの<code>List</code>を返すことが確認できます。</li>
<li><code>JsfUtil.getSelectItems</code>に移動します。マウスを<code>getSelectItems</code>の上に移動し、[Ctrl] (Macの場合は[&#8984])を押し、表示されるリンクをクリックします。<br><br><strong class="notes">注意:</strong> <code>JsfUtil</code>は、<a href="#jsfPagesEntityClasses">エンティティからのJSFページ・クラス・ウィザード</a>の完了時に生成されたユーティリティ・クラスの1つであることを思い出してください。<br><br>このメソッドは、エンティティのリスト(<code>ConsultantStatus</code>オブジェクトの<code>List</code>など)をループし、各エンティティに<code>SelectItem</code>を作成します。次に太字で示すように<strong></strong>、各<code>SelectItem</code>はエンティティ・オブジェクトとオブジェクトのラベル<em></em>を使用して作成されます。
<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>このラベルは、エンティティの<code>toString()</code>メソッドを使用して作成され、レスポンスでレンダリングされるときのオブジェクトの表現です。<code>SelectItem(java.lang.Object value, java.lang.String label)</code>コンストラクタに対するJavadocの定義を参照してください。</p>
<p>
これで、ドロップダウン・リストに項目を表示するときにブラウザにレンダリングされるのがエンティティの<code>toString()</code>メソッドであることを確認したので、<code>ConsultantStatus</code><code>toString()</code>メソッドを変更します。</p>
</li>
<li>エディタで<code>ConsultantStatus</code>エンティティ・クラスを開きます。<code>statusId</code>および<code>description</code>を返すように、<code>toString</code>メソッドを変更します。これらは、<code>CONSULTANT_STATUS</code>表の2つの列に対応するエンティティ・プロパティです。
<pre class="examplecode">public String toString() {
return <strong>statusId + ", " + description;</strong>
}</pre></li>
<li>プロジェクトを再実行します。ブラウザに開始ページが表示されたら、「<code>Show All Consultant Items</code>」リンクをクリックし、「<code>Create New Consultant</code>」をクリックします。
<p>
<code>StatusId</code>」ドロップダウン・リストを確認します。これで、データベースの<code>CONSULTANT_STATUS</code>表に格納されている、あるレコードについてのステータスIDと説明が表示されるようになりました。</p>
<img alt="「StatusId」ドロップダウン・リストのブラウザ表示" class="margin-around b-all" src="../../../images_www/articles/72/web/jsf20-crud/drop-down.png" title="ConsultantStatusエンティティのtoString()メソッドによる、「StatusId」ドロップダウン・リストへの項目の表示">
</li>
</ol>
</div>
<h2 id="troubleshooting">トラブルシューティング</h2>
<p>構成によっては、サーバーへのアプリケーションのデプロイが失敗し、「出力」ウィンドウに次のメッセージが表示されることがあります。
</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>失敗する最も一般的な原因は、サーバーでJDBCリソースを生成する際の問題です。その場合、「出力」ウィンドウのサーバー・ログ・タブに次のようなメッセージが表示されます。
</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>サーバー・ログ・タブが開かれていない場合は、「サービス」ウィンドウの「GlassFish Server」ノードを右クリックし、「ドメイン・サーバー・ログの表示」を選択して開くことができます。</p>
<p>このアプリケーションには、2つのJDBCリソースが必要です。</p>
<ul>
<li>JDBCリソースまたはデータ・ソース。アプリケーションでは、JNDIルックアップを使用してJDBCリソースを検索します。持続性ユニットを調べると(<code>persistence.xml</code>)、このアプリケーションのJTAデータ・ソースのJNDI名が<code>jdbc/consult</code>であることがわかります。
<p>JDBCリソースは、アプリケーションで現在使用されている接続プールを識別します。</p></li>
<li>JDBC接続プール。接続プールは、場所、ユーザー名、パスワードなど、データベースの接続詳細を指定します。このアプリケーションで使用される接続プールは<code>consultPool</code>です。</li>
</ul>
<p>JDBCリソースと接続プールは<code>glassfish-resources.xml</code>ファイルで指定されます。<code>glassfish-resources.xml</code>を開くには、「プロジェクト」ウィンドウで「サーバー・リソース」ノードを展開し、ファイルをダブルクリックします。ファイルには、次のような情報が記載されています。</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><code>glassfish-resources.xml</code>では、JDBCリソース<code>jdbc/consult</code><code>consultPool</code>を接続プールの名前として識別していることがわかります。<code>consultPool</code>のプロパティも確認できます。このアプリケーションでは、1つのデータ・ソースと1つの接続プールのみが<code>glassfish-resources.xml</code>で定義されます。場合によっては、開発またはテストのみに使用する一時データ・ソースを識別するために、追加リソースを指定することもできます。</p>
<p>アプリケーションの実行時に、JDBCリソースおよび接続プールがサーバーで自動的に生成されなかった場合、次の手順を実行して、GlassFish管理コンソールでリソースを手動で作成できます。</p>
<ol>
<li>まだ開いていない場合、エディタで<code>glassfish-resources.xml</code>を開きます。
<p>JDBCリソースと接続プールを作成する際は、<code>glassfish-resources.xml</code>で指定されているプロパティ値を使用します。</p></li>
<li>「サービス」ウィンドウで「GlassFish Server」ノードを右クリックし、ポップアップ・メニューで「ドメイン管理コンソールを開く」を選択して、ブラウザでGlassFishコンソールを開きます。</li>
<li>GlassFishコンソールの共通タスク・ナビゲーション・パネルで、<strong>「JDBC」</strong>ノードおよび<strong>「JDBCリソース」</strong>および<strong>「JDBC接続プール」</strong>ノードを展開します。<br> <a href="../../../images_www/articles/80/web/jsf20-crud/gf-admin-console-lg.png"> <img alt="GlassFish管理コンソールのブラウザ表示" class="margin-around b-all" src="../../../images_www/articles/80/web/jsf20-crud/gf-admin-console-sm.png" title="クリックしてフルサイズ画像のGlassFish管理コンソールを表示"></a>
<p>現在サーバーに登録されているDBCリソースを確認できます。<code>jdbc/consult</code><code>consultPool</code>が共通タスク・ナビゲーション・パネルの「JDBC」ノードの下に表示されていない場合は、これらを作成する必要があります。一部のJDBCリソースは、サーバーのインストール時にデフォルトで作成されており、これらはサブノードとして表示されます。 </p></li>
<li><strong>「JDBC接続プール」</strong>ノードをクリックし、新規のJDBC接続プール・ペインで「新規」をクリックします。<br> <img alt="新規のJDBC接続プール・ペインのブラウザ表示" class="margin-around b-all" src="../../../images_www/articles/80/web/jsf20-crud/gf-new-jdbc-pool1.png" title="GlassFish管理コンソールの新規のJDBC接続プール・ペイン"></li>
<li>プール名として<strong>consultPool</strong>を入力し、リソース・タイプとして<strong>javax.sql.ConnectionPoolDataSource</strong>を選択し、データベース・ドライバ・ベンダーとして<strong>MySql</strong>を選択します。「次」をクリックします。</li>
<li>手順2で、<strong>URL</strong><strong>username</strong>および<strong>password</strong>プロパティの値を検索して指定します。「終了」をクリックします。 <br> <img alt="新規のJDBC接続プール・ペインの2番目のパネルのブラウザ表示" class="margin-around b-all" src="../../../images_www/articles/80/web/jsf20-crud/gf-new-jdbc-pool2.png" title="GlassFish管理コンソールの新規のJDBC接続プール・パネル">
<p class="tips"><code>glassfish-resources.xml</code>で、プロパティの値を検索できます。</p>
<p>「終了」をクリックするとサーバー上に新規の接続プールが作成され、「JDBC接続プール」ノードの下にその接続プールのノードが表示されます。</p></li>
<li>共通タスク・ナビゲーション・パネルで<strong>「JDBCリソース」</strong>をクリックして、「新規」をクリックします。</li>
<li>JNDI名に<strong>jdbc/consult</strong>と入力し、「プール名」ドロップダウン・リストで<strong>consultPool</strong>を選択します。「OK」をクリックします。 <br> <img alt="新規のJDBCリソース・ペインのブラウザ表示" class="margin-around b-all" src="../../../images_www/articles/80/web/jsf20-crud/gf-new-jdbc-resource.png" title="GlassFish管理コンソールの新規のJDBCリソース・ペイン">
<p>「OK」をクリックするとサーバー上に新規のJDBCリソースが作成され、「JDBCリソース」ノードの下にそのリソースのノードが表示されます。</p>
<p>IDEの「サービス」ウィンドウで、「GlassFish Server」の下の「リソース」を展開して、そのIDEで新規リソースが追加されたことを確認できます。変更内容を表示するために、ビューのリフレッシュが必要になることがあります(「リソース」を右クリックして「リフレッシュ」を選択)。</p>
<img alt="IDEの「サービス」ウィンドウのスクリーンショット" class="margin-around b-all" src="../../../images_www/articles/80/web/jsf20-crud/gf-services-jdbc-resources.png" title="IDEの「サービス」ウィンドウに表示されたJDBCリソース"></li>
</ol>
<p>MySQLおよびIDEの使用時に問題を解決するためのヒントについては、次のドキュメントを参照してください。</p>
<ul>
<li><a href="../ide/mysql.html">MySQLデータベースへの接続</a>のチュートリアル</li>
<li><a href="mysql-webapp.html#troubleshoot">MySQLデータベースを使用した単純なWebアプリケーションの作成</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">このチュートリアルに関するご意見をお寄せください</a>
</div>
<br style="clear:both;" />
<h2 id="seealso">関連項目</h2>
<p>JSF 2.xの詳細は、次のリソースを参照してください。</p>
<div class="indent">
<h3>NetBeansの記事およびチュートリアル</h3>
<ul>
<li><a href="jsf20-intro.html">NetBeans IDEでのJavaServer Faces 2.x入門</a></li>
<li><a href="jsf20-support.html">NetBeans IDEでのJSF 2.xのサポート</a></li>
<li><a href="../../samples/scrum-toys.html">Scrum Toys - JSF 2.0の完全版サンプル・アプリケーション</a></li>
<li><a href="../javaee/javaee-gettingstarted.html">Java EEアプリケーションの開始</a></li>
<li><a href="../../trails/java-ee.html">Java EEおよびJava Webの学習</a></li>
</ul>
<h3>外部リソース</h3>
<ul>
<li><a href="http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html">JavaServer Facesテクノロジ</a> (公式ホーム・ページ)</li>
<li><a href="http://jcp.org/aboutJava/communityprocess/final/jsr314/index.html">JSR 314 JavaServer Faces 2.0の仕様</a></li>
<li>Java EE 7チュートリアルの<a href="http://docs.oracle.com/javaee/7/tutorial/doc/jsf-intro.htm">JavaServer Facesテクノロジ</a>の章</li>
<li><a href="http://javaserverfaces.dev.java.net/">GlassFishプロジェクトMojarra</a> (JSF 2.xの公式リファレンス実装)</li>
<li><a href="http://forums.oracle.com/forums/forum.jspa?forumID=982">OTNディスカッション・フォーラム: JavaServer Faces</a></li>
<li><a href="http://www.jsfcentral.com/">JSF Central</a></li>
</ul>
<h3>ブログ</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>