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のページで調べてみて下さい。 |