データベースからのJavaServer Faces 2.x CRUDアプリケーションの生成

This tutorial needs a review. You can open a JIRA issue, or edit it in GitHub following these contribution guidelines.

このチュートリアルでは、NetBeans IDEを使用し、バックエンドのデータベースと対話するWebアプリケーションを作成します。このアプリケーションでは、データベースに格納されたデータを表示および変更できます。この機能は_CRUD_ (作成、読取り、更新、削除)とも呼ばれます。開発するアプリケーションは、次のテクノロジに基づきます。

  • JavaServer Faces (JSF) 2.x。フロント・エンドのWebページ、検証処理およびリクエスト-レスポンス・サイクルの管理に使用します。

  • Java Persistence API (JPA) 2.0。EclipseLinkを使用してデータベースからエンティティ・クラスを生成し、トランザクションを管理します。EclipseLinkはJPAのリファレンス実装であり、GlassFishサーバーのデフォルトの持続性プロバイダです。

  • Enterprise JavaBeans (EJB) 3.1。エンティティ・クラスにアクセスするステートレスEJBを提供し、アプリケーションのビジネス・ロジックを格納します。

IDEには、アプリケーション用のコードをすべて生成する、2つのウィザードが用意されています。データベースからのエンティティ・クラス・ウィザードを使用すると、提供されたデータベースからエンティティ・クラスを生成できます。エンティティ・クラスを作成した後は、エンティティからのJSFページ・クラス・ウィザードを使用して、そのエンティティ・クラスのJSF管理対象BeanとEJB、およびエンティティ・クラス・データのビューを処理する一連のFaceletsページを作成します。このチュートリアルの最後のアプリケーションの操作の項には、このアプリケーションの理解を深め、IDEの習熟に役立つ様々な課題を用意しています(オプション)。

このチュートリアルを完了するには、次のソフトウェアとリソースが必要です。

ソフトウェアまたはリソース 必須バージョン

NetBeans IDE

7.2、7.3、7.4、8.0、Java EEバンドル版

Java Development Kit (JDK)

7または8

GlassFish Server Open Source Edition

3.x、4.x

mysql-consult.zip (MySQL) または javadb-consult.zip (JavaDB)

n/a

*注意: *

  • NetBeans IDEのJava EEバンドル版には、このチュートリアルに必要な、Java EE準拠サーバーのGlassFishサーバーも含まれています。

  • このチュートリアルのソリューション・プロジェクトを入手するには、ConsultingAgencyJSF20.zipをダウンロードしてください。

データベースの作成

このチュートリアルでは、`consult`という名前のコンサルティング・エージェンシ・データベースを使用します。このデータベースはIDEのインストールに含まれないため、このチュートリアルを開始する前に、まずデータベースを作成する必要があります。

`consult`データベースは、様々なデータベース構造を処理するIDEサポートの幅広さを示すことを目的として設計されました。したがって、推奨されるデータベース設計の一例やベスト・プラクティスを示すものではありません。かわりに、データベース設計に使用できる関連機能の多くを取り入れようとしています。たとえば、`consult`データベースには、すべての関係タイプ、複合主キー、および多数の異なるデータ型が含まれています。データベース構造の詳しい概要については、このページの後に出てくる表を参照してください。

*注意: *

  • このチュートリアルではMySQLデータベース・サーバーを使用しますが、JavaDBデータベース・サーバーを使用してチュートリアルを完了することもできます。JavaDBでデータベースを作成するには、javadb-consult.zipアーカイブをダウンロードして抽出します。このアーカイブには、`consult`データベースを作成、ドロップおよび生成するためのSQLスクリプトが含まれています。

  • MySQLを操作するためのIDEの構成については、MySQLデータベースへの接続のチュートリアルを参照してください。

  • JavaDBを操作するIDEの構成については、Java DB (Derby)データベースの操作のチュートリアルを参照してください。

MySQLとGlassFishの組合せ:

MySQLを使用する場合で、GlassFish v3またはOpen Source Edition 3.0.1を使用するときは、データベースがパスワードで保護されていることを確認する必要があります。(詳細は、GlassFishの問題12221を参照してください。)パスワードが設定されていないデフォルトのMySQL`root`アカウントを使用している場合は、コマンド行プロンプトからパスワードを設定できます。

たとえば、パスワードを`nbuser`に設定するには、コマンド行プロンプトで次のコマンドを入力します。

shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('_nbuser_') WHERE User = 'root';
mysql> FLUSH PRIVILEGES;

mysql: command not found」というエラーが表示される場合は、mysql`コマンドが`PATH`環境変数に追加されていません。かわりにMySQLのインストール・ディレクトリの`bin`ディレクトリのフル・パスを入力することで、コマンドをコールできます。たとえば、`mysql`コマンドがコンピュータ上の/usr/local/mysql/bin`にある場合は、次のように入力します。

shell> /usr/local/mysql/bin/mysql -u root

詳細は、MySQL公式リファレンス・マニュアルの以下を参照してください。

次の手順を実行してデータベースを作成し、IDEからそのデータベースに接続します。

  1. mysql-consult.zipをダウンロードし、アーカイブをローカル・システムに抽出します。アーカイブを抽出すると、データベースを作成および生成するためのSQLスクリプトが表示されます。このアーカイブには、ドロップする表のためのスクリプトも含まれています。

  2. 「サービス」ウィンドウで「データベース」ノードを展開し、「MySQL」ノードを右クリックして「サーバーを起動」を選択します。

  3. 「MySQLサーバー」ノードを右クリックし、「データベースを作成」を選択します。

  4. 「MySQLデータベースの作成」ダイアログでデータベース名として「consult」と入力します。「OK」をクリックします。「データベース」ノードの下に新しいノードが表示されます(jdbc:mysql://localhost:3306/consult [デフォルト・スキーマのroot])。

  5. 新しいノードを右クリックし、「接続」を選択します。

  6. メイン・メニューから「ファイル」>「ファイルを開く」を選択し、抽出したファイル`mysql_create_consult.sql`に移動します。「開く」をクリックします。ファイルがSQLエディタで自動的に開きます。

run sql script
Figure 1. IDEのエディタ内でSQLファイルを開く
  1. SQLエディタ・ツールバーの「接続」ドロップダウン・リストで`consult`データベースが選択されていることを確認し、「SQLの実行」(run sql btn)ボタンをクリックします。

「SQLの実行」をクリックすると、「出力」ウィンドウに次の出力が表示されます。

run sql output
Figure 2. SQL実行時の情報が表示された「出力」ウィンドウ

データベース構造の確認

表が正しく作成されたかどうかを確認するには、データベース接続ノードの下の「表」ノードを展開します。表のノードを展開すると、表の列、索引および外部キーを確認できます。列を右クリックして「プロパティ」を選択すると、その列に関する追加情報が表示されます。

services window tables
Figure 3. データベース接続、表、表の列、索引および外部キーが表示された「サービス」ウィンドウ

注意: 「表」ノードの下に表が表示されない場合は、「表」ノードを右クリックし、「リフレッシュ」を選択します。

`consult`データベースの構造を見ると、様々な関係と様々な型のフィールドを含む表がデータベースにあることがわかります。データベースからエンティティ・クラスを作成するときは、フィールドの型ごとに適したコードが自動的に生成されます。

diagram consult
Figure 4. consultデータベースのエンティティ関係図

次の表では、`consult`データベース内の表について説明します。

データベース表 説明 設計の特徴

CLIENT

コンサルティング・エージェンシのクライアント

生成されない複合主キー(フィールドは外部キーを構成しない)

CONSULTANT

クライアントが契約に基づいて雇うことができる、コンサルティング・エージェンシの従業員

LONG VARCHAR型のresumeフィールドを含む

CONSULTANT_STATUS

コンサルティング・エージェンシでのコンサルタントのステータス(「Active」や「Inactive」などのステータスが考えられる)

生成されないCHAR型の主キー

RECRUITER

クライアントとコンサルタントのやり取りを担当する、コンサルティング・エージェンシの従業員

 

PROJECT

クライアントがコンサルティング・エージェンシのコンサルタントを要員として充てるプロジェクト

CLIENT表に対する外部キーを構成する2つのフィールドを含む、生成されない複合主キー

BILLABLE

コンサルタントがプロジェクトの任務に費やし、コンサルティング・エージェンシが関連クライアントに対して請求する時間数

CLOB型のartifactフィールドを含む

ADDRESS

クライアントの請求先住所

 

PROJECT_CONSULTANT

コンサルタントが現在割り当てられているプロジェクトを示す結合表

PROJECTとCONSULTANTとを相互参照し、PROJECTには複合主キーがある

`consult`データベースには、様々な関係が含まれています。エンティティ・クラスをデータベースから作成する場合、列のSQL型に基づいて、適切なJava型のプロパティが自動的に生成されます。次の表では、`consult`データベースのエンティティ関係を説明します。逆方向の関係は示していません。

エンティティ 関連するエンティティ 関係の情報 説明

CLIENT

RECRUITER

手動編集ありでnull可能な1対1の関係、編集なしでnull可能な1対多の関係

CLIENTには多数のRECRUITERがあり、RECRUITERには0または1つのCLIENTがあります(手動で編集されていない場合)

CLIENT

ADDRESS

null可能ではない1対1の関係

CLIENTには1つのADDRESSがあり、ADDRESSには0または1つのCLIENTがあります

CLIENT

PROJECT

null可能ではない1対多の関係、Projectエンティティのclientフィールドの値はProjectの主キーの一部

CLIENTには多数のPROJECTがあり、PROJECTには1つのCLIENTがあります

CONSULTANT

PROJECT

多対多

CONSULTANTには複数のPROJECTがあり、PROJECTには多数のCONSULTANTがあります

CONSULTANT

BILLABLE

null可能ではない1対多の関係

CONSULTANTには多数のBILLABLEがあり、BILLABLEには1つのCONSULTANTがあります

CONSULTANT_STATUS

CONSULTANT

null可能ではない1対多の関係

CONSULTANT_STATUSには多数のCONSULTANTがあり、CONSULTANTには1つのCONSULTANT_STATUSがあります

CONSULTANT

RECRUITER

null可能な1対多の関係

CONSULTANTには0または1つのRECRUITERがあり、RECRUITERには多数のCONSULTANTがあります

BILLABLE

PROJECT

null可能ではない1対多の関係

BILLABLEには1つのPROJECTがあり、PROJECTには多数のBILLABLEがあります

データベースが作成されたので、次にWebアプリケーションを作成し、データベースからのエンティティ・クラス・ウィザードを使用して、データベースの表に基づいてエンティティ・クラスを生成できます。

Webアプリケーション・プロジェクトの作成

この課題では、Webプロジェクトを作成し、JavaServer Facesフレームワークをプロジェクトに追加します。プロジェクトを作成するときは、新規プロジェクト・ウィザードの「フレームワーク」パネルで「JavaServer Faces」を選択します。

  1. メイン・メニューから「ファイル」>「新規プロジェクト」([Ctrl]-[Shift]-[N]、Macの場合は[⌘]-[Shift]-[N])を選択します。

  2. 「Java Web」カテゴリから「Webアプリケーション」を選択します。「次」をクリックします。

  3. プロジェクト名として「ConsultingAgency」と入力し、プロジェクトの場所を設定します。「次」をクリックします。

  4. サーバーを「GlassFish」に設定し、「Java EEバージョン」を「Java EE 6 Web」または「Java EE 7 Web」に設定します。「次」をクリックします。

  5. 「フレームワーク」パネルで「JavaServer Faces」オプションを選択します。「終了」をクリックします。

「終了」をクリックすると、IDEはWebアプリケーション・プロジェクトを生成し、`index.xhtml`がエディタに表示されます。

データベースからのエンティティ・クラスの生成

IDEでデータベースに接続した後、データベースからのエンティティ・クラス・ウィザードを使用して、データベース内の表に基づいてすばやくエンティティ・クラスを生成できます。IDEでは、選択した各表のエンティティ・クラスを生成でき、関連する表に必要なエンティティ・クラスを生成することもできます。

  1. 「プロジェクト」ウィンドウで「ConsultingAgency」プロジェクト・ノードを右クリックし、「新規」>「データベースからのエンティティ・クラス」を選択します。このオプションがリストにない場合は「その他」を選択します。次に、ファイル・ウィザードで「持続性」カテゴリを選択し、「データベースからのエンティティ・クラス」を選択します。

  2. 「データ・ソース」ドロップダウン・リストから「新しいデータ・ソース」を選択して「データ・ソースを作成」ダイアログを開きます。

  3. 「JNDI名」に「jdbc/consult」と入力し、「データベース接続」に「jdbc:mysql://localhost:3306/consult」接続を選択します。

create datasource
Figure 5. データソースを作成するためのJNDI名およびデータベース接続の指定
  1. 「OK」をクリックしてダイアログ・ボックスを閉じ、ウィザードに戻ります。`consult`データベース内の表が「使用可能な表」リスト・ボックスに表示されます。

  2. 「すべてを追加」ボタンをクリックし、データベースに格納されているすべての表を選択します。「次」をクリックします。

new entities wizard
  1. 「パッケージ」名に「jpa.entities」と入力します。

  2. 名前付き問合せを生成するためのチェックボックスと持続性ユニットを作成するためのチェックボックスが選択されていることを確認します。「終了」をクリックします。

「終了」をクリックすると、IDEは、プロジェクトの`jpa.entities`パッケージにエンティティ・クラスを生成します。

ウィザードを使用してデータベースからエンティティ・クラスを作成するとき、IDEでデータベース表間の関係が確認されます。「プロジェクト」ウィンドウで「jpa.entities」パッケージ・ノードを展開すると、IDEによって`PROJECT_CONSULTANT`表を除くすべての表のエンティティ・クラスを生成されていることがわかります。`PROJECT_CONSULTANT`のエンティティ・クラスが作成されなかった理由は、この表が結合表であるためです。

projects window entities
Figure 6. 生成されたエンティティ・クラスが表示された「プロジェクト」ウィンドウのスクリーンショット

また、IDEは複合主キーを持つ`CLIENT`と`PROJECT`の各表に2つの追加クラスを生成します。これらの表の主キー・クラス(ClientPK.java`と`ProjectPK.java)の名前には、`PK`が付加されています。

エンティティ・クラスに生成されたコードを見ると、エンティティ・クラスの自動生成IDフィールドに`@GeneratedValue`注釈が、一部のフィールドに`@Basic(optional="false")注釈がウィザードによって追加されていることがわかります。エンティティからのJSFページ・クラス・ウィザードでは、@Basic(optional="false")`注釈に基づき、これらのフィールドでnull可能ではない列の違反を防止するためのチェック機能を含むコードを生成できます。

エンティティ・クラスからのJSFページの生成

エンティティ・クラスが作成されたので、次にデータを表示および変更するためのWebインタフェースを作成できます。ここでは、エンティティからのJSFページ・クラス・ウィザードを使用して、JavaServer Facesページを生成します。ウィザードで生成されるコードは、エンティティ・クラス内に格納された持続性注釈に基づいて生成されます。

ウィザードでは、エンティティ・クラスごとに次のファイルが生成されます。

  • AbstractFacade.java を拡張するステートレス・セッションBean

  • JSFセッション・スコープ指定管理対象Bean

  • CRUD機能のための4つのFaceletsファイル(Create.xhtmlEdit.xhtmlList.xhtml、および`View.xhtml`)を格納するディレクトリ

ウィザードでは、次のファイルも生成します。

  • エンティティ・インスタンスの作成、取得、変更および除去のためのビジネス・ロジックを含む AbstractFacade.java クラス

  • JSF管理対象Bean (JsfUtilPaginationHelper)に使用されるユーティリティ・クラス

  • ローカライズされたメッセージのプロパティ・バンドル、およびプロジェクトのFaces構成ファイル内(このファイルがない場合、`faces-config.xml`ファイルが作成される)の対応するエントリ

  • レンダリングされるコンポーネントのデフォルトのスタイル・シートおよびFaceletsテンプレート・ファイルを含む、補助Webファイル

JSFページを生成するには:

  1. 「プロジェクト」ウィンドウで、プロジェクト・ノードを右クリックし、「新規」>「エンティティからのJSFページ・クラス」を選択してウィザードを開始します。このオプションがリストにない場合は「その他」を選択します。次に、ファイル・ウィザードで、「JavaServer Faces」カテゴリを選択し、「エンティティからのJSFページ・クラス」を選択します。

「利用可能なエンティティ・クラス」ボックスに、プロジェクトに含まれる7つのエンティティ・クラスが一覧表示されます。このボックスには、組込み可能なクラス(ClientPK.java`と`ProjectPK.java)は一覧表示されません。

  1. 「すべてを追加」をクリックして、すべてのクラスを「選択されているエンティティ・クラス」ボックスに移動します。

newjsf wizard
Figure 7. プロジェクトに含まれるすべてのエンティティ・クラスが表示された「新規エンティティからのJSFページ・クラス」ウィザード

「次」をクリックします。

  1. ウィザードのステップ3の「生成されたJSFページとクラス」で、「JPAセッションBeanパッケージ」に「jpa.session」と入力します。

  2. 「JSFクラス・パッケージ」に「jsf」と入力します。

  3. 「ローカリゼーション・バンドル名」フィールドに「/resources/Bundle」と入力します。これにより、`resources`という名前のパッケージが生成され、これに`Bundle.properties`ファイルが属します。ここを空白のままにした場合、プロパティ・バンドルはプロジェクトのデフォルトのパッケージ内に作成されます。

newjsf wizard2
Figure 8. 生成されたファイルに対するパッケージ名とフォルダ名の指定

IDEをプロジェクトの規則により適応させるために、ウィザードで生成した任意のファイルをカスタマイズできます。「テンプレートのカスタマイズ」リンクをクリックし、ウィザードで使用されるファイル・テンプレートを変更します。

customize template
Figure 9. ウィザードで生成されたファイルの「テンプレートをカスタマイズ」

一般に、IDEで管理されるすべてのテンプレートには、「テンプレート・マネージャ」(「ツール」>「テンプレート」)を使用してアクセスし、変更を加えることができます。

  1. 「終了」をクリックします。ステートレス・セッションBeanが`jpa.session`パッケージ内に生成され、JSFセッション・スコープ指定管理対象Beanが`jsf`パッケージ内に生成されます。各ステートレス・セッションBeanは、対応するエンティティ・クラスの操作を処理します。これには、Java Persistence APIを経由したエンティティ・クラスのインスタンスの作成、編集および破棄が含まれます。各JSF管理対象Beanは、`javax.faces.convert.Converter`インタフェースを実装し、対応するエンティティ・クラスのインスタンスと`String`型オブジェクトの間の変換作業を行います。

「Webページ」ノードを展開すると、エンティティ・クラスごとにフォルダが生成されたことがわかります。各フォルダには、Create.xhtmlEdit.xhtml、`List.xhtml`および`View.xhtml`ファイルが格納されます。`index.xhtml`ファイルも変更され、各`List.xhtml`ページへのリンクが挿入されます。

projects jsfpages
Figure 10. ウィザードによって生成された、各エンティティの「Facelets」ページ

各JSF管理対象Beanは、4つの対応するFaceletsファイルに固有のもので、適切なセッションBean内のメソッドを呼び出すコードが格納されます。

resources」フォルダ・ノードを展開し、ウィザードで生成されたデフォルトの`jsfcrud.css`スタイル・シートを検索します。アプリケーションの開始ページ(index.xhtml)またはFaceletsテンプレート・ファイル(template.xhtml)をエディタで開くと、次のようなスタイル・シートへの参照が表示されます。

<h:outputStylesheet name="css/jsfcrud.css"/>

Faceletsテンプレート・ファイルは、各エンティティ・クラスの4つの各Faceletsファイルで使用されます。

「ソース・パッケージ」ノードを展開すると、セッションBeans、JSF管理対象Bean、ユーティリティ・クラス、およびウィザードで生成されたプロパティ・バンドルが確認できます。

projects generated classes70
Figure 11. ウィザードによって生成されたクラスが表示された「プロジェクト」ウィンドウの「ソース・パッケージ」ディレクトリのスクリーンショット

ウィザードでは、プロパティ・バンドルの場所を登録するためのFaces構成ファイル(faces-config.xml)も生成されます。「構成ファイル」ノードを展開し、`faces-config.xml`をXMLエディタで開くと、次のエントリが格納されていることがわかります。

<application>
    <resource-bundle>
        <base-name>/resources/Bundle</base-name>
        <var>bundle</var>
    </resource-bundle>
</application>

また、新規`resources`パッケージを展開すると、クライアントのデフォルト言語のメッセージが格納されている`Bundle.properties`ファイルがあります。このメッセージは、エンティティ・クラス・プロパティから派生します。

新規プロパティ・バンドルを追加するには、`Bundle.properties`ファイルを右クリックし、「カスタマイズ」を選択します。「カスタマイザ」ダイアログで、新しいロケールをアプリケーションに追加できます。

アプリケーションの操作

これで、エンティティ・クラス、エンティティ・クラスを制御するためのEJBセッションBeans、データベースを表示および編集するためのJSFによるフロント・エンドがプロジェクトに組み込まれたので、プロジェクトを実行して結果を確認してみます。

次に、このアプリケーションとIDEで提供される機能の習熟に役立つ、一連の短い課題を示します(オプション)。

完了したプロジェクトの確認

  1. プロジェクトを実行するには、「プロジェクト」ウィンドウでプロジェクトのノードを右クリックして「実行」を選択するか、メイン・ツールバーで「プロジェクトの実行」(run project btn)ボタンをクリックします。

アプリケーションの開始ページが表示されると、リンク・リストが表示され、これらを使用して各データベース表に格納されたエントリを表示できます。

welcome page links
Figure 12. 各表のデータベースの内容を表示するためのリンク

これらのリンクは、エンティティからのJSFページ・クラス・ウィザードを完了したら、開始ページ(index.xhtml)に追加されます。これらはコンサルティング・エージェンシ・データベース上でCRUD機能を提供するFaceletsページへのエントリ・ポイントとして提供されます。

<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>
  1. Show All Consultant Items」リンクをクリックします。前出のコードを参照すると、ターゲット・ページが`/consultant/List.xhtml`であることがわかります。(JSF 2.xでは、ファイル拡張子は暗黙のナビゲーションによって推定されます。)

empty consultants list
Figure 13. コンサルタント表は現在空

このデータベースには、現在サンプル・データが含まれていません。「Create New Consultant」リンクをクリックし、表示されるWebフォームを使用することでデータを手動で追加できます。これにより、`/consultant/Create.xhtml`ページの表示がトリガーされます。また、SQLスクリプトをIDEで実行し、サンプル・データを含む表を生成することもできます。次の項では、両方の選択肢を示します。

indexリンクをクリックすると、開始ページ内に一覧表示されたリンクに戻ることができます。これらのリンクには、各データベース表が保持するデータのビューと、各エンティティ・フォルダの`List.xhtml`ファイルを表示するためのトリガーがあります。後述の説明にあるように、データを表に追加した後、各エントリに他のリンクが表示され、単一の表レコードのデータを表示(View.xhtml)、編集(Edit.xhmtl)および破棄できます。

*注意:*アプリケーションのデプロイに失敗した場合は、下の「トラブルシューティング」セクションを参照してください。(MySQLデータベースを使用した単純なWebアプリケーションの作成の「トラブルシューティング」セクションも参照してください。)

SQLスクリプトを使用したデータベースの生成

提供されたスクリプトを実行します。このスクリプトにより、データベース表のサンプル・データが生成されます。このスクリプト(mysql_insert_data_consult.sql)はコンサルティング・エージェンシ・データベースのZIPファイルに格納されており、必要なソフトウェアの表からダウンロードできます。

操作するデータベース・サーバー(MySQLまたはJavaDB)に応じて、提供されているスクリプトを実行できます。このスクリプトにより、データベース表のサンプル・データが生成されます。MySQLの場合は、`mysql_insert_data_consult.sql`スクリプトになります。JavaDBの場合は、`javadb_insert_data_consult.sql`スクリプトになります。どちらのスクリプトも、必要なソフトウェアの表からダウンロードできるそれぞれのアーカイブの中に含まれています。

  1. メイン・メニューから「ファイル」>「ファイルを開く」を選択し、コンピュータ上のスクリプトの場所に移動します。「開く」をクリックします。ファイルがIDEのSQLエディタで自動的に開きます。

  2. SQLエディタのツールバーの「接続」ドロップダウン・リストで`consult`データベースが選択されていることを確認します。

run sql insert
Figure 14. IDEのSQLエディタ内でスクリプトを開く

エディタ内を右クリックして「文の実行」を選択するか、「SQLの実行」(run sql btn)ボタンをクリックします。スクリプトの実行結果は「出力」ウィンドウで確認できます。

  1. GlassFishサーバーを再起動します。`consult`データベースに含まれる新しいデータをサーバーが再ロードしたり、キャッシュに保存できるようにするには、このステップが必要となります。そのためには、「出力」ウィンドウのGlassFishサーバーのタブ(GlassFishサーバーのタブにはサーバーのログが表示される)をクリックし、左マージンにある「サーバーを再起動」(glassfish restart)ボタンをクリックします。サーバーが停止し、再起動します。

  2. プロジェクトを再度実行し、「Show All Consultant Items」リンクをクリックします。リストが空でなくなっていることがわかります。

consultants list small

NetBeansのデータベース・サポート

IDEのデータベース表ビューアを使用すると、管理されている表データをデータベース内で直接表示および変更できます。たとえば、`consultant`表を「サービス」ウィンドウで右クリックし、「データを表示」を選択します。

view data
Figure 15. データベース表の右クリック・メニューによる「データを表示」の選択

アクションの実行に使用されるSQL問合せがエディタの上部に表示され、表のグラフィカル・ビューが下部に表示されます。

view data table small

表のセルの内側をダブルクリックして、データへのインライン変更を実行します。「レコードをコミット」(commit records icon)アイコンをクリックし、変更内容をデータベースにコミットします。

グラフィカル・ビューには多数の機能が用意されています。詳細は、Database Support in NetBeans IDEでのデータベースのサポートを参照してください。

Faceletsページでのエディタのサポートの確認

  1. エディタで`/consultant/List.xhtml`ページを開きます。レンダリングするFaceletsの`template.xhtml`ファイルに依存するページが8行目に示されます。

<ui:composition template="/template.xhtml">

行番号を表示するには、エディタの左マージンを右クリックし、「行番号を表示」を選択します。

  1. IDEの「ファイル」ダイアログを使用し、template.xhtml`を開きます。[Alt]-[Shift]-[O] (Macの場合は[Ctrl]-[Shift]-[O])を押して、「`template」と入力します。

go to file
Figure 16. 「ファイルに移動」ダイアログを使用してプロジェクト・ファイルを速やかに開く

「OK」をクリックするか、[Enter]を押します。

  1. このテンプレートは、他のファイルからタイトルと本体に内容を挿入するための`<ui:insert>`タグを適用します。`<ui:insert>`タグの上にカーソルを置いて、[Ctrl]-[Space]を押し、ドキュメント・ポップアップ・ウィンドウを呼び出します。

doc popup
Figure 17. [Ctrl]-[Space]の押下による、Faceletsタグでのドキュメント・ポップアップの呼出し

JSFタグおよびその属性上で[Ctrl]-[Space]を押すと、ドキュメント・ポップアップを呼出しできます。表示されるドキュメントは、公式のJSFタグ・ライブラリ・ドキュメントで提供されている説明から取得したものです。

  1. List.xhtml`ファイルに戻ります([Ctrl]-[Tab]を押します)。<ui:define>`タグは、テンプレートのタイトルと本体に適用する内容を定義するために使用されます。このパターンは、各エンティティ・クラスに対して生成される4つのFaceletsファイル(Create.xhtmlEdit.xhtmlList.xhtml、および`View.xhtml`)すべてに使用されます。

  2. `Bundle.properties`ファイルに含まれる、ローカライズされたメッセージに使用される任意のEL式にカーソルを置きます。[Ctrl]-[Space]を押してローカライズされたメッセージを表示します。

localized messages small

前出のイメージに、「List」を解決するEL式が表示されています。これは、テンプレートのタイトルに適用され、ブラウザにレンダリングされるページから確認できます。

  1. ファイルの最下部にスクロールし、92行目にある「Create New Consultant」リンクのコードに移動します。この内容は次のとおりです。

<h:commandLink action="#{consultantController.prepareCreate}" value="#{bundle.ListConsultantCreateLink}"/>
  1. `commandLink`の`action`属性の上で[Ctrl]-[Space]を押し、ドキュメント・ポップアップを呼び出します。

`action`属性は、ブラウザ内でリンクがクリックされた際のリクエストを処理するメソッドを示します。次のドキュメントが表示されます。

ユーザーがこのコンポーネントをアクティブ化したときに起動するアプリケーション・アクションを表すメソッド式。この式は、パラメータを取得せず、オブジェクト(論理的な結果を取得するためにコールされるtoString()オブジェクト)を返すpublicメソッドに評価される必要があり、このオブジェクトはこのアプリケーションのNavigationHandlerに渡されます。 つまり、`action`値は通常、`String`型として評価されるJSF管理対象Bean内のメソッドを参照します。この文字列は、リクエストを適切なビューに転送するため、JSFの`NavigationHandler`に使用されます。これは次の手順で確認します。

  1. カーソルを`consultantController`の上に置き、[Ctrl]-[Space]を押します。エディタのコード補完で、`consultantController`がJSF管理対象Beanであることが示されます。

code completion managed bean
Figure 18. JSF管理対象Beanに対して提供されるコード補完
  1. カーソルを`prepareCreate`に移動し、[Ctrl]-[Space]を押します。コード補完によって、`ConsultantController`管理対象Bean内に格納されたメソッドの一覧が表示されます。

code completion properties
Figure 19. クラス・メソッドに対して提供されるコード補完
  1. [Ctrl] (Macの場合は[⌘])を押し、マウスを`prepareCreate`の上に移動します。リンクが形成され、このリンクを使用して`ConsultantController`管理対象Bean内の`prepareCreate()`メソッドに直接移動できます。

editor navigation
Figure 20. エディタのナビゲーションを使用した、ソース・コードへの速やかな移動
  1. リンクをクリックし、次に示す`prepareCreate()`メソッドを表示します。

public String prepareCreate() {
    current = new Consultant();
    selectedItemIndex = -1;
    return "Create";
}

このメソッドは、Create`を返します。`NavigationHandler`はバックグラウンドで情報を収集し、リクエストに対するレスポンスとして送信されるビューをターゲットとするパスに`Create`文字列を適用します(/consultant/Create.xhtml`)。(JSF 2.xでは、ファイル拡張子は暗黙のナビゲーションによって推定されます。)

フィールド検証を使用したデータベース整合性の確認

  1. ブラウザのConsultants Listページから、「Create New Consultant」リンクをクリックします。前の項で説明したように、これによって`/consultant/Create.xhtml`ページのレンダリングがトリガーされます。

  2. 次の詳細をフォームに入力します。ここでは`RecruiterId`フィールドと`StatusId`フィールドの両方を空白のままにします。

フィールド

ConsultantId

2

電子メール

jack.smart@jsfcrudconsultants.com

パスワード

jack.smart

HourlyRate

75

BillableHourlyRate

110

HireDate

07/22/2008

Resume

I’m a great consultant. Hire me - You won’t be disappointed!

RecruiterId

---

StatusId

---

  1. 「保存」をクリックします。これを実行すると、`StatusId`フィールドに検証エラーのフラグが表示されます。

create new consultant
Figure 21. フォームへのサンプル・データの入力

なぜこの状態になるのでしょうか。コンサルティング・エージェンシ・データベースのエンティティの関係図を再度考察するとわかります。前出のリレーショナル表にあるように、`CONSULTANT`表および`CONSULTANT_STATUS`表はnull可能ではない1対多の関係を共有しています。そのため、`CONSULTANT`表のすべてのエントリには、`CONSULTANT_STATUS`表内のエントリに対する参照が含まれている必要があります。これは、2つの表をリンクする`consultant_fk_consultant_status`外部キーによって示されています。

表に保持されている外部キーは、「サービス」ウィンドウ([Ctrl]-[5]、Macの場合は[⌘]-[5])で表の「外部キー」ノードを展開すると表示できます。

consultant fk
Figure 22. 「サービス」ウィンドウでの外部キー属性の調査
  1. 検証エラーを解決するには、「StatusId」ドロップダウン・リストから「entity.ConsultantStatus[statusId=A]」を選択します。

注意: `RecruiterId`フィールドは空白のままでかまいません。データベースのエンティティ関係図に示すとおり、`CONSULTANT`表と`RECRUITER`表との間には、null可能な1対多の関係があります。これは、`CONSULTANT`内のエントリは`RECRUITER`エントリと関連付ける必要がないということです。

  1. 「保存」をクリックします。consultantのエントリが正常に保存されたことを示すメッセージが表示されます。「Show All Consultant Items」をクリックすると、表にリストされた新規エントリが表示されます。

一般に、生成されたFaceletsページには、次のことが発生するユーザー入力に対してエラーを表示します。

  • null可能ではない表のセルに対する空のフィールド。

  • 主キーなどの変更できないデータの変更。

  • 型が正しくないデータの挿入。

  • ユーザーのビューがデータベースと同期していないときのデータの変更。

エンティティ・クラスの編集

前の項で、ユーザーにとってわかりやすくない「entity.ConsultantStatus[statusId=A]」オプションを「StatusId」ドロップダウン・リストに表示する方法を確認しました。ドロップダウン・リストの各項目に表示されるテキストは、たとえばエンティティ・クラスの`toString()`メソッドがコールされることよって発生した、各`ConsultantStatus`エンティティに対する文字列表現であることがすでにおわかりでしょう。

この項では、締めくくりとして、エディタのコード補完、ドキュメント、およびナビゲーション・サポートを使用する方法を説明します。また、ユーザーにとってよりわかりやすいメッセージをドロップダウン・リストに表示する方法も示します。

  1. エディタで`/consultant/Create.xhtml`ファイルを開きます。これは、先ほどブラウザで表示した「Create New Consultant」フォームです。次に*太字*で示す、「StatusId」ドロップダウン・リストのコードまでスクロールします。

    <h:outputLabel value="#{bundle.CreateConsultantLabel_resume}" for="resume" />
    <h:inputTextarea rows="4" cols="30" id="resume" value="#{consultantController.selected.resume}" title="#{bundle.CreateConsultantTitle_resume}" />
    *<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>*
    <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>
  1. `<f:selectItems>`タグに適用される`value`を確認します。`value`属性は、ドロップダウン・リストの各項目に表示するテキストを決定します。

`itemsAvailableSelectOne`上で[Ctrl]-[Space]を押します。エディタのコード補完に、`ConsultantStatusController`の`getItemsAvailableSelectOne()`メソッドが`SelectItem`オブジェクトの配列を返すことが示されます。

code completion returned object
Figure 23. メソッドに対して返されるクラスが表示されたコード補完
  1. [Ctrl] (Macの場合は[⌘])を押し、マウスを`itemsAvailableSelectOne`の上に移動します。リンクが形成され、このリンクを使用して`ConsultantStatus`エンティティのソース・コード内の`getItemsAvailableSelectOne()`メソッドに直接移動できます。リンクをクリックします。

  2. メソッド署名内の`SelectItem[]`戻り値の上にカーソルを置き、[Ctrl]-[Space]を押してドキュメント・ポップアップを呼び出します。

documentation select item
Figure 24. [Ctrl]-[Space]の押下によるドキュメント・サポートの呼出し

ドキュメント・ウィンドウの「Webブラウザ」(web browser icon)アイコンをクリックし、外部WebブラウザでJavadocを開きます。

表示されるように、SelectItem`クラスはJSFフレームワークに属しています。このドキュメントにあるように、`UISelectOne`コンポーネントは、前出のステップ1で調べたマークアップからの<h:selectOneMenu>`タグによって表現されます。

  1. [Ctrl] (Macの場合は[⌘])を押し、マウスを`findAll()`の上に移動します。ポップアップが表示され、メソッド署名が示されます。

method signature
Figure 25. エディタでのメソッド署名のポップアップの表示

ここで、`ejbFacade.findAll()`が`ConsultantStatus`オブジェクトの`List`を返すことが確認できます。

  1. `JsfUtil.getSelectItems`に移動します。マウスを`getSelectItems`の上に移動し、[Ctrl] (Macの場合は[⌘])を押し、表示されるリンクをクリックします。

注意: `JsfUtil`は、エンティティからのJSFページ・クラス・ウィザードの完了時に生成されたユーティリティ・クラスの1つであることを思い出してください。

このメソッドは、エンティティのリスト(`ConsultantStatus`オブジェクトの`List`など)をループし、各エンティティに`SelectItem`を作成します。次に太字で示すように、各`SelectItem`はエンティティ・オブジェクトとオブジェクトのラベルを使用して作成されます。

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++;
    }
    *for (Object x : entities) {
        items[i++] = new SelectItem(x, x.toString());
    }*
    return items;
}

このラベルは、エンティティの`toString()`メソッドを使用して作成され、レスポンスでレンダリングされるときのオブジェクトの表現です。`SelectItem(java.lang.Object value, java.lang.String label)`コンストラクタに対するJavadocの定義を参照してください。

これで、ドロップダウン・リストに項目を表示するときにブラウザにレンダリングされるのがエンティティの`toString()`メソッドであることを確認したので、`ConsultantStatus``toString()`メソッドを変更します。

  1. エディタで`ConsultantStatus`エンティティ・クラスを開きます。`statusId`および`description`を返すように、`toString`メソッドを変更します。これらは、`CONSULTANT_STATUS`表の2つの列に対応するエンティティ・プロパティです。

public String toString() {
    return *statusId + ", " + description;*
}
  1. プロジェクトを再実行します。ブラウザに開始ページが表示されたら、「Show All Consultant Items」リンクをクリックし、「Create New Consultant」をクリックします。

StatusId」ドロップダウン・リストを確認します。これで、データベースの`CONSULTANT_STATUS`表に格納されている、あるレコードについてのステータスIDと説明が表示されるようになりました。

drop down
Figure 26. ConsultantStatusエンティティのtoString()メソッドによる、「StatusId」ドロップダウン・リストへの項目の表示

トラブルシューティング

構成によっては、サーバーへのアプリケーションのデプロイが失敗し、「出力」ウィンドウに次のメッセージが表示されることがあります。

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.

失敗する最も一般的な原因は、サーバーでJDBCリソースを生成する際の問題です。その場合、「出力」ウィンドウのサーバー・ログ・タブに次のようなメッセージが表示されます。

Severe:   Exception while preparing the app : Invalid resource : jdbc/consult__pm
com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Invalid resource : jdbc/consult__pm

サーバー・ログ・タブが開かれていない場合は、「サービス」ウィンドウの「GlassFish Server」ノードを右クリックし、「ドメイン・サーバー・ログの表示」を選択して開くことができます。

このアプリケーションには、2つのJDBCリソースが必要です。

  • JDBCリソースまたはデータ・ソース。アプリケーションでは、JNDIルックアップを使用してJDBCリソースを検索します。持続性ユニットを調べると(persistence.xml)、このアプリケーションのJTAデータ・ソースのJNDI名が`jdbc/consult`であることがわかります。

JDBCリソースは、アプリケーションで現在使用されている接続プールを識別します。

  • JDBC接続プール。接続プールは、場所、ユーザー名、パスワードなど、データベースの接続詳細を指定します。このアプリケーションで使用される接続プールは`consultPool`です。

JDBCリソースと接続プールは`glassfish-resources.xml`ファイルで指定されます。`glassfish-resources.xml`を開くには、「プロジェクト」ウィンドウで「サーバー・リソース」ノードを展開し、ファイルをダブルクリックします。ファイルには、次のような情報が記載されています。

<?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>

`glassfish-resources.xml`では、JDBCリソース`jdbc/consult`が`consultPool`を接続プールの名前として識別していることがわかります。`consultPool`のプロパティも確認できます。このアプリケーションでは、1つのデータ・ソースと1つの接続プールのみが`glassfish-resources.xml`で定義されます。場合によっては、開発またはテストのみに使用する一時データ・ソースを識別するために、追加リソースを指定することもできます。

アプリケーションの実行時に、JDBCリソースおよび接続プールがサーバーで自動的に生成されなかった場合、次の手順を実行して、GlassFish管理コンソールでリソースを手動で作成できます。

  1. まだ開いていない場合、エディタで`glassfish-resources.xml`を開きます。

JDBCリソースと接続プールを作成する際は、`glassfish-resources.xml`で指定されているプロパティ値を使用します。

  1. 「サービス」ウィンドウで「GlassFish Server」ノードを右クリックし、ポップアップ・メニューで「ドメイン管理コンソールを開く」を選択して、ブラウザでGlassFishコンソールを開きます。

  2. GlassFishコンソールの共通タスク・ナビゲーション・パネルで、「JDBC」*ノードおよび「JDBCリソース」および「JDBC接続プール」*ノードを展開します。

gf admin console sm

現在サーバーに登録されているDBCリソースを確認できます。`jdbc/consult`と`consultPool`が共通タスク・ナビゲーション・パネルの「JDBC」ノードの下に表示されていない場合は、これらを作成する必要があります。一部のJDBCリソースは、サーバーのインストール時にデフォルトで作成されており、これらはサブノードとして表示されます。

  1. *「JDBC接続プール」*ノードをクリックし、新規のJDBC接続プール・ペインで「新規」をクリックします。

gf new jdbc pool1
Figure 27. GlassFish管理コンソールの新規のJDBC接続プール・ペイン
  1. プール名として*consultPool*を入力し、リソース・タイプとして*javax.sql.ConnectionPoolDataSource*を選択し、データベース・ドライバ・ベンダーとして*MySql*を選択します。「次」をクリックします。

  2. 手順2で、URL、*username*および*password*プロパティの値を検索して指定します。「終了」をクリックします。

gf new jdbc pool2
Figure 28. GlassFish管理コンソールの新規のJDBC接続プール・パネル

`glassfish-resources.xml`で、プロパティの値を検索できます。

「終了」をクリックするとサーバー上に新規の接続プールが作成され、「JDBC接続プール」ノードの下にその接続プールのノードが表示されます。

  1. 共通タスク・ナビゲーション・パネルで*「JDBCリソース」*をクリックして、「新規」をクリックします。

  2. JNDI名に*jdbc/consult*と入力し、「プール名」ドロップダウン・リストで*consultPool*を選択します。「OK」をクリックします。

gf new jdbc resource
Figure 29. GlassFish管理コンソールの新規のJDBCリソース・ペイン

「OK」をクリックするとサーバー上に新規のJDBCリソースが作成され、「JDBCリソース」ノードの下にそのリソースのノードが表示されます。

IDEの「サービス」ウィンドウで、「GlassFish Server」の下の「リソース」を展開して、そのIDEで新規リソースが追加されたことを確認できます。変更内容を表示するために、ビューのリフレッシュが必要になることがあります(「リソース」を右クリックして「リフレッシュ」を選択)。

gf services jdbc resources
Figure 30. IDEの「サービス」ウィンドウに表示されたJDBCリソース

MySQLおよびIDEの使用時に問題を解決するためのヒントについては、次のドキュメントを参照してください。

関連項目