About

ドキュメント

プロジェクト文書

Built by Maven

コンフィグレーション

ここでは,Kuina-Daoで複数の永続ユニットを使用する場合や,Kuina-Daoをカスタマイズする方法について説明します.

異なった構成を持つ複数の永続ユニットの使用

異なった構成をもつ複数の永続ユニットを使用するには,以下の命名規約とパッケージ構成に従うことを推奨します. 推奨する命名規約とパッケージ構成に従うと,エンティティとマッピングファイルは対応する永続ユニットに自動的に登録されます.

推奨する命名規約
永続ユニット名は"persistenceUnit", もしくは"任意のプレフィックスPersistenceUnit"とする.

マッピングファイル名は"任意のプレフィックスOrm.xml"とする.

推奨するパッケージ構成
永続ユニット"persistenceUnit"に属するエンティティは ルートパッケージ.entityに配置する.

永続ユニット"任意のプレフィックスPersistenceUnit"に属するエンティティは ルートパッケージ.entity.任意のプレフィックスに配置する.

永続ユニット"persistenceUnit"に属するマッピングファイルは ルートパッケージ.entity,もしくはルートパッケージ.daoに配置する.

永続ユニット"任意のプレフィックスPersistenceUnit"に属するマッピングファイルは ルートパッケージ.entity.任意のプレフィックス, もしくはルートパッケージ.dao.任意のプレフィックスに配置する.

"persistenceUnit"という名称の永続ユニットと "hogePerisitenceUnit"という名称の永続ユニットがそれぞれ存在する場合, 推奨されるパッケージ構成は次のようになります. この例でのルートパッケージはkuina.dao.examleとします. Emp.class,Dept.class,Sales.classはエンティティとします. また,登場するxmlファイルはすべてJPAのマッピングファイルとします.

  • kuina.dao.examle.dao.EmpDao.class
  • kuina.dao.examle.dao.EmpOrm.xml
  • kuina.dao.examle.dao.DeptDao.class
  • kuina.dao.examle.dao.DeptOrm.xml
  • kuina.dao.examle.dao.hoge.SalesDao.class
  • kuina.dao.examle.dao.hoge.SalesOrm.xml
  • kuina.dao.examle.entity.Emp.class
  • kuina.dao.examle.entity.Dept.class
  • kuina.dao.examle.entity.hoge.Sales.class

EmpOrm.xmlDeptOrm.xmlEmp.classDept.classが永続ユニットpersistenceUnitに登録されます. 残りの,SalesOrm.xmlSales.classが 永続ユニットhogePerisitenceUnitに登録されます.

同一の構成を持つ複数の永続ユニットの使用

同一の構成を持つ複数の永続ユニットを作成する場合,エンティティやDAOを共有したままコンテキストに応じて データベースの接続先を切り替えることができます.

推奨する命名規約とパッケージ構成に従えば,エンティティとマッピングファイルは対応する永続ユニットに 自動的に登録されます.

推奨する命名規約
永続ユニット名は"persistenceUnit"以外とする.

マッピングファイル名は"任意のプレフィックスOrm.xml"とする.

推奨するパッケージ構成
エンティティはルートパッケージ.entityに配置する.

マッピングファイルはルートパッケージ.entity, もしくはルートパッケージ.daoに配置する.

推奨する設定ファイル定義例

まずデータベースの接続先ごとにデータソースの設定を行います. この例ではH2とDerbyを使います. データベースごとの設定ファイルとそれを束ねるひとつの設定ファイルを用意します.

  • h2-jdbc.dicon
  • derby-jdbc.dicon
  • jdbc.dion

それぞれのファイルの定義は以下のようになります. 設定上の注意点は太字にしています. 一部定義を省略しています.

h2-jdbc.dicon

namespaceには"jdbc"を指定します. DataSourceを表すコンポーネントの名前は "任意のプレフィックスDataSource"にする必要があります. ここでは"h2DataSource"とします.

<components namespace="jdbc
">
  <include path="jta.dicon"/>
  <include path="jdbc-extension.dicon"/>
  
  ...(略)...

  <component name="h2DataSource
"
    class="org.seasar.extension.dbcp.impl.DataSourceImpl"
  />
</components>
derby-jdbc.dicon

namespaceには"jdbc"を指定します. DataSourceを表すコンポーネントの名前は "任意のプレフィックスDataSource"にする必要があります. ここでは"derbyDataSource"とします.

<components namespace="jdbc
">
  <include path="jta.dicon"/>
  <include path="jdbc-extension.dicon"/>

  ...(略)...

  <component name="derbyDataSource
"
    class="org.seasar.extension.dbcp.impl.DataSourceImpl"
  />

</components>
jdbc.dicon

データベースごとに用意した設定ファイルをインクルードします. namespaceには"jdbc"を指定します. SelectableDataSourceProxyを定義しコンポーネントの名前は "dataSource"とします.

<components namespace="jdbc
">
  <include path="h2-jdbc.dicon"/>
  <include path="derby-jdbc.dicon"/>

  <component name="dataSource
"
    class="org.seasar.extension.datasource.impl.SelectableDataSourceProxy
"/>

</components>

次に永続ユニットごとの設定を用意します.

  • persistence.xml
  • jpa.dicon
  • h2-jpa.dicon
  • derby-jpa.dicon

それぞれの設定ファイルは以下のようになります (この例はJPA実装にHibernateを使う場合の設定です).

persistence.xml

永続ユニットを複数定義します. 接続先のデータベースは自動的に切り替えるのでデータソースは同じ名前でかまいません.

<persistence>
  <persistence-unit name="h2PersistenceUnit
" transaction-type="JTA">
    <jta-data-source>jdbc/dataSource</jta-data-source>
    ...(略)...
  </persistence-unit>

  <persistence-unit name="derbyPersistenceUnit
" transaction-type="JTA">
    <jta-data-source>jdbc/dataSource</jta-data-source>
    ...(略)...
  </persistence-unit>
</persistence>    
h2-jpa.dicon

永続ユニットh2PersistenceUnit用の設定ファイルです.

ContainerPersistenceUnitProviderabstractUnitNameプロパティには Seasar2でのデフォルトの永続ユニット名であるpersistenceUnitを, unitNameプロパティには実際の永続ユニットであるh2PersistenceUnitを設定します. unitNameプロパティの永続ユニットに自動で検出されたエンティティとマッピングファイルが登録されます.

EntityManagerを表すコンポーネントの名前は "対応するデータソースのプレフィックスEntityManager"にする必要があります.

<components>
  <include path="s2hibernate-jpa.dicon"/>

  <component name="h2PersistenceUnitProvider
"
      class="org.seasar.framework.jpa.impl.ContainerPersistenceUnitProvider">
    <property name="abstractUnitName">"persistenceUnit
"</property>
    <property name="unitName">"h2PersistenceUnit
"</property>
  </component>

  <component name="h2EntityManagerFactory
" class="javax.persistence.EntityManagerFactory">
    h2PersistenceUnitProvider
.entityManagerFactory
  </component>

  <component name="h2EntityManager
"
      class="org.seasar.framework.jpa.impl.TxScopedEntityManagerProxy"/>
</components>
derby-jpa.dicon

永続ユニットderbyPersistenceUnit用の設定ファイルです.

ContainerPersistenceUnitProviderabstractUnitNameプロパティには Seasar2でのデフォルトの永続ユニット名であるpersistenceUnitを, unitNameプロパティには実際の永続ユニットであるderbyPersistenceUnitを設定します. unitNameプロパティの永続ユニットに自動で検出されたエンティティとマッピングファイルが登録されます.

EntityManagerを表すコンポーネントの名前は "対応するデータソースのプレフィックスEntityManager"にする必要があります.

<components>
  <include path="s2hibernate-jpa.dicon"/>

  <component name="derbyPersistenceUnitProvider
"
      class="org.seasar.framework.jpa.impl.ContainerPersistenceUnitProvider">
    <property name="abstractUnitName">"persistenceUnit
"</property>
    <property name="unitName">"derbyPersistenceUnit
"</property>
  </component>

  <component name="derbyEntityManagerFactory
" class="javax.persistence.EntityManagerFactory">
    derbyPersistenceUnitProvider
.entityManagerFactory
  </component>

  <component name="derbyEntityManager
"
      class="org.seasar.framework.jpa.impl.TxScopedEntityManagerProxy"/>
</components>
jpa.dicon

永続ユニットごとに用意した設定ファイルをインクルードします. SelectableEntityManagerProxyを定義しコンポーネントの名前は "entityManager"とします.

<components>
  <include path="h2-jpa.dicon"/>
  <include path="derby-jpa.dicon"/>
  
  <component name="entityManager
"
      class="org.seasar.framework.jpa.impl.SelectableEntityManagerProxy
"/>

</components>

実行方法

コンテキストを指定して接続先のデータベースを切り替えるには org.seasar.extension.datasource.DataSourceFactoryコンポーネントの setSelectableDataSourceName(String)メソッドに, データソースのプレフィックスを引数として渡して実行します.

例えば,上記の定義に従った場合,Derbyに接続するにはsetSelectableDataSourceName("derby")を呼び出し, H2に接続するにはsetSelectableDataSourceName("h2")を呼び出します.

値を設定する場所としては,Servelet FilterやAOPのロジックが適しています.

Kuina-Daoのカスタマイズ

Kuina-Daoが提供するインターフェースを実装したクラスを作成し設定ファイルを適切に定義することでKuina-Daoをカスタマイズできます. たとえば,新しい機能を追加する場合次の作業が必要です.

  • org.seasar.kuina.dao.internal.Commandインターフェースの実装クラスを作成する.
  • org.seasar.kuina.dao.internal.CommandBuilderインターフェースの実装クラスを作成する.
  • kuina-dao-builder.diconをコピーした設定ファイルにCommandBuilderの実装クラスを登録する.
  • s2container.diconに上記で新しく作成した設定ファイルを使用することを指定する.

設定例

org.seasar.kuina.dao.internal.Commandの実装クラスの作成

Commandインタフェースを実装するクラスを作成しDAOメソッドに適応したい処理を記述します. このクラスではEntityManagerに対し問い合わせや更新などを実行できます.

executeメソッドの戻り値はDAOメソッドの戻り値となります. DAOメソッドが戻り値を持たない場合,executeメソッドではnullを返してください.

public class HogeCommand implements Command
 {
  public Object execute(EntityManager em, Object[] arguments) {
    ...
    return null;
  }
}
org.seasar.kuina.dao.internal.CommandBuilderの実装クラスの作成

CommandBuilderインターフェースを実装するクラスを作成しCommandを生成するための処理を記述します.

buildメソッドはDAOメソッドのシグネチャ等の情報から対応するCommandを生成します. 生成しない場合はnullを返してください.

public class HogeCommandBuilder implements CommandBuilder
 {
  public Command build(Class<?> daoClass, Method method) {
    if (!method.getName().startsWith("hoge")) {
      return null;
    }
    ...
    return new HogeCommand();
  }
}
kuina-dao-builder.diconのコピーの作成

kuina-dao-x.x.x.jarに同梱されているkuina-dao-builder.diconをコピーしてカスタマイズ用の設定ファイルを作成し, 新規に作成したCommandBuilderを登録します.

たとえば,コピーしたファイルをmy-kuina-dao-builder.diconという名前にし 次のように新しいCommandBuilderを定義します.

<components namespace="kuinaDaoBuilder">
  <include path="convention.dicon"/>
  <include path="javaee5.dicon"/>

  <component class="org.seasar.kuina.dao.internal.metadata.DaoMetadataFactoryImpl"/>
  <component instance="prototype" class="org.seasar.kuina.dao.internal.metadata.DaoMetadataImpl"/>

  <component class="org.seasar.kuina.dao.internal.builder.SqlCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.SqlUpdateCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.NamedQueryCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.NamedQueryUpdateCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.FindAllQueryCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.ExampleQueryCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.DtoQueryCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.ParameterQueryCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.ConditionalQueryCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.FindCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.GetReferenceCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.ContainsCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.PersistCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.RemoveCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.MergeCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.RefreshCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.ReadLockCommandBuilder"/>
  <component class="org.seasar.kuina.dao.internal.builder.WriteLockCommandBuilder"/>
  <component class="kuina.dao.example.HogeCommandBuilder"/>

</components>
s2container.diconの設定

S2Containerの振る舞いを制御する設定ファイルであるs2container.diconkuina-dao-builder.diconの替わりにカスタマイズ用の設定ファイルを使用することを指定します.

カスタマイズ用の設定ファイルがmy-kuina-dao-builder.diconという名前である場合,次のように記述します.

<components>
    <include condition="#ENV == 'ut'" path="hotdeploy.dicon"/>
    <include condition="#ENV != 'ut'" path="cooldeploy.dicon"/>

    <component class="org.seasar.framework.container.factory.SimplePathResolver">
        <initMethod name="addRealPath">
            <arg>"kuina-dao-builder.dicon
"</arg>
            <arg>"my-kuina-dao-builder.dicon
"</arg>
        </initMethod>
    </component>
</components>