CayenneのDataObject定義

これから作ろうとするものは簡単な掲示板です。
投稿されたメッセージを時間順に表示し、返信もできるようにしてみます。

まずは、データをどのように定義するかと言う事で、最初にやる事はDataObjectを定義する所から始まります。

DataObjectとはEOFで言う所のEOEnterpriseObjectになります。
WebObjectsでは、このEOEnterpriseObject(訳してEOとよく言う)を作るためには、EOModelerというツールを使います。
Cayenneでは、EOModelerに相当するツールが備わっていて、CayenneModelerといいます。
こいつでDataObjectを作っていきます。


掲示板の発言を一つのオブジェクトと考え、Messageというクラスを考えてみます。

同時に、データベースはmessageというテーブルを一つ用意し、対応する項目をセットします。


実際にCayenneModelerで組み立てた様子がこれです。(クリックで拡大表示)


Messageオブジェクト(ObjEntity)


messageスキーマ(DbEntity)


この画像を見て、WebObjects開発者なら一目で何やっているか分かるでしょう。
それくらい、CayenneModelerはEOModelerと似ています。

ちなみに、下の画像はEOModelerで同じように組んでみたものです。

Messageオブジェクトのプライマリキーはidです。
この掲示板はレスを付ける事ができるため、MessageオブジェクトにparentIdというキーを設けて、レスはレス元のMessageオブジェクトを参照します。
つまり、自分自身にリレーションを張っていると言う事です。

Message.id > Message.parentId
toParentリレーション(To Oneリレーション)
Message.parentId >> Message.id
childrenリレーション(To Manyリレーション)


このCayenneModelerではCayenneが必要とする設定ファイルを自動で書き出してくれます。
中身はXMLファイルです。
EOModelerで言う所のEOModelファイルに相当します。

ちなみに、上記のモデルは以下のようになりました。

cayenne.xml

<?xml version="1.0" encoding="utf-8"?>
<domains project-version="1.1">
<domain name="MessageBoard">
	<map name="MessageBoard" location="MessageBoard.map.xml"/>

	<node name="hsqldb"
		 datasource="hsqldb.driver.xml"
		 adapter="org.objectstyle.cayenne.dba.hsqldb.HSQLDBAdapter"
		 factory="org.objectstyle.cayenne.conf.DriverDataSourceFactory">
			<map-ref name="MessageBoard"/>
	 </node>
</domain>
</domains>

MessageBoard.map.xml

<?xml version="1.0" encoding="utf-8"?>
<data-map project-version="1.1">
	<db-entity name="message">
		<db-attribute name="content" type="VARCHAR" isMandatory="true" length="1200"/>
		<db-attribute name="id" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
		<db-attribute name="m_date" type="TIMESTAMP" isMandatory="true"/>
		<db-attribute name="mail" type="VARCHAR" length="120"/>
		<db-attribute name="p_id" type="INTEGER"/>
		<db-attribute name="s_date" type="TIMESTAMP" isMandatory="true"/>
		<db-attribute name="subject" type="VARCHAR" length="120"/>
		<db-attribute name="url" type="VARCHAR" length="120"/>
		<db-attribute name="user_name" type="VARCHAR" isMandatory="true" length="120"/>
		<db-attribute name="user_pass" type="VARCHAR" length="10"/>
	</db-entity>
	<obj-entity name="Message" className="bbs.data.Message" dbEntityName="message">
		<obj-attribute name="content" type="java.lang.String" db-attribute-path="content"/>
		<obj-attribute name="mail" type="java.lang.String" db-attribute-path="mail"/>
		<obj-attribute name="modificationDate" type="java.util.Date" db-attribute-path="m_date"/>
		<obj-attribute name="parentId" type="java.lang.Integer" db-attribute-path="p_id"/>
		<obj-attribute name="subject" type="java.lang.String" db-attribute-path="subject"/>
		<obj-attribute name="submitDate" type="java.util.Date" db-attribute-path="s_date"/>
		<obj-attribute name="url" type="java.lang.String" db-attribute-path="url"/>
		<obj-attribute name="userName" type="java.lang.String" db-attribute-path="user_name"/>
		<obj-attribute name="userPass" type="java.lang.String" db-attribute-path="user_pass"/>
	</obj-entity>
	<db-relationship name="children" source="message" target="message" toMany="true">
		<db-attribute-pair source="id" target="p_id"/>
	</db-relationship>
	<db-relationship name="toParent" source="message" target="message" toMany="false">
		<db-attribute-pair source="p_id" target="id"/>
	</db-relationship>
	<obj-relationship name="children" source="Message" target="Message" db-relationship-path="children"/>
	<obj-relationship name="toParent" source="Message" target="Message" db-relationship-path="toParent"/>
</data-map>

hsqldb.driver.xml

<?xml version="1.0" encoding="utf-8"?>
<driver project-version="1.1" class="org.hsqldb.jdbcDriver">
	<url value="jdbc:hsqldb:hsql://localhost:9001"/>
	<connectionPool min="1" max="1" />
	<login userName="sa"/>
</driver>

もちろん、上記ファイルを手で書く事も可能です。
が、やっぱりここはCayenneModelerを使ってモデリングする方がいいでしょう!

あ、ちなみに開発環境ですが、以下の通りです。

$ java -version
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-69.1)
Java HotSpot(TM) Client VM (build 1.4.1_01-24, mixed mode)

なお、上記組み合わせで行くと、CayenneTapestryの両方で使っているJakarta Commonsのjarのバージョン不一致が起こります。
試行錯誤してみた結果、以下の組み合わせで安定しました。ご参考までに。

  • ashwood.jar
  • bsf-2.3.0.jar
  • cayenne-nodeps.jar
  • commons-beanutils-1.6.1.jar
  • commons-codec-1.2.jar
  • commons-collections-3.1.jar
  • commons-digester-1.5.jar
  • commons-fileupload-1.0.jar
  • commons-lang-2.0.jar
  • commons-logging-1.0.2.jar
  • hsqldb.jar
  • jakarta-oro-2.0.6.jar
  • javassist-2.5.1.jar
  • jgraph.jar
  • log4j-1.2.6.jar
  • ognl-2.6.3.jar
  • tapestry-3.0.jar
  • tapestry-contrib-3.0.jar