MENU

J2EE環境構築編

J2EE体験編

J2EE体験編
CMPその2 auto_incrementを利用する

CMPを利用してデータを取得することが出来たので、次はデータの入力に挑戦です。
CMPの場合、create()を実行することで、SQLのinsertが実行されます。

それならgetHome().create(id,name)で良いんじゃないの、と思ったあなた。確かにそのとおり。
しかし、id番号として一意の数を割り当てようとすると、ちょっと気になることがあります。「データベースの中で一番大きなid番号を取得する」「その番号に1を加えてcreateする」という処理を考えてみると、1つのcreate処理の完了前に別途の番号取得の要求があると、結果として同じid番号を発行してしまう可能性がある、ということです。

また、MySQLにはauto_incrementという仕組みがあって、勝手に一意の数を割り振ってくれる(この表現は正確ではありませんが、そのように利用することが出来ます)機能が備わっています。先ほどの例で見れば、nameしかinsertしていないのに、勝手にidに1がinsertされています。これを利用すれば、コーディングの量を減らすことが出来ます。既にtableの定義ではauto_incrementを指定してしまっています。
ここは是が非でもこの機能を利用しなければなりません。

auto_incrementをめぐる問題

さて、方針としてauto_incrementを利用することを確定したわけですが、原則としてCMPではcreate()の実行にprimary keyが必要なので、そのままではauto_incrementを利用できません。
つまり、CMPを利用するにはprimary key(idのことです)を決めてからcreate()を実行しなければならず、insertを実行しなければid(これはprimary keyです)は確定しない。にっちもさっちもいかない状態になってしまうわけです。

解決策

前振りがちょっと長くなってしまいました。いろいろ調べた結果、結構簡単にこの問題を解決する方法がありました。しかも、それはjbossに最初から用意されています。
手順としては

xdoclet.xmlの修正
Test1Bean.javaにtagを追加

という二点だけです。

xdoclet.xmlの修正

xdoclet.xmlの<jboss>を修正します。その1でも修正したファイルです。
今度は

version="3.0"

version="3.2"

にします。これによって、test1ejb/META-INF/jbosscmp-jdbc.xmlの冒頭のdtd宣言が3_0から3_2になります。もちろん、jbosscmp-jdbc.xmlを修正する、という方法でも良いのですが、jbosscmp-jdbc.xmlは「Generate EJB class」を実行するたびに生成されるので、そのたびに書き換えなければなりません。xdoclet.xmlを書き換えておくことをお薦めします。

tagの追加

どのフィールドにauto_incrementを利用するか、tagに記述します。
Test1Bean.javaをダブルクリックしてエディタに表示します。このファイルの構造は

import文
コメント(各種タグを含む)
クラス宣言
コメント(各種タグを含む)
メソッド定義
以下、コメント、メソッド定義の繰り返し

という形になっています。
最初に、import文とクラス宣言の間にタグを追加します。
ここのコメントは

lomboz-definition
xdoclet-definition

という構造になっています。この中のxdoclet-definitionに

* @jboss.entity-command name="mysql-get-generated-keys"

というタグを追加します。xdoclet-definitionの中ならどこでもいいですが、既存のタグの構造を破壊しないようにしましょう。

次に、getId()メソッドの上のコメント部分にもうひとつタグを追加します。
ここでもxdoclet-definitionの内側に追加するように、また、既存のタグの構造を破壊しないように注意しましょう。
追加するのは

* @jboss.persistence auto-increment="true"

というタグです。

これでauto_incrementを利用できるようになりました。これでクラスを再生成すればできあがり・・・。ではありません。
Test1Bean.javaにちょっと修正を加えなければ、ブラウザからの入力をデータベースに入力できません。
まず、

ejbCreate(String name)

というように引数を書き加えます。

次にreturn nullの前の行に

setName(name);

と追加します。ejbPostCreateにも

ejbPostCreate(String name)

と追加します。
最後にsetEntityContextとunsetEntityContextを追加します。

protected EntityContext ctx;
public void setEntityContext(EntityContext ec){
	this.ctx=ec;
}
public void unsetEntityContext(){
	this.ctx=null;
}

EntityContextを利用するためにimportも追加します。

import javax.ejb.EntityContext;

今度こそ、クラスを生成しましょう。

確認

確認するのはtest1ejbの中のjbosscmp-jdbc.xmlです。
正しく設定されていれば、冒頭のdtdが

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jbosscmp-jdbc PUBLIC "-//JBoss//DTD JBOSSCMP-JDBC 3.2//EN" "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_3_2.dtd">

になっています。また、

         <cmp-field>
            <field-name>id</field-name>
            <column-name>id</column-name>

            <jdbc-type>VARCHAR</jdbc-type>
            <sql-type>int</sql-type>

			<auto-increment/>
        </cmp-field>
	
	<entity-command name="mysql-get-generated-keys">
	</entity-command>

というようにauto-incrementとentity-commandが追加されます。
そのようになっていない場合はどこかに間違いがあるので、じっくり眺めて間違いを修正しましょう。

クライアントの作成

「Lomboz JSP Wizard」を利用して、add.jspを追加します。
show.jspにはフォームを追加してテキストを入力できるようにします。
add.jsp
show.jsp
フォームに空白だけを入力したり、一文字も入力しないまま送信すると、入力を促すメッセージが、何かを入力して送信すると、それが追加された旨のメッセージが表示されるはずです。

タグの意味について

タグの意味を知りたい人は、xdocletのページで調べてみて下さい。