サブデータベースで順序を使う

最終更新日: 2021年12月8日
R8 | R9

準備

スクリプトで主キーの値をセットする場合は、利用者が主キー項目に値を入力しないよう、下記の設定を追加することを推奨します。

  • モデル項目詳細定義 > 入力制御 > 隠し・読み込み専用を設定する。
  • 全画面 読み込み専用を "有効" にする。
  • 登録画面 隠し項目を "有効" にする。
  • コピー登録画面 隠し項目を "有効" にする。

例 PostgreSQLからserial値を取得する

顧客モデル (customer) の主キー項目 (customerid) に順序の値をセットします。
「ヘルパ > 登録」のタイミングに次のスクリプトを用意します。

  // デフォルトで用意されている session はメインデータベース用です。
  // サブデータベース1 にアクセスするには sessionFactory2 から session を取得して下さい。
  // サブデータベース2 では sessionFactory3 となります。 
  var session2 = p.appctx.getBean("sessionFactory2").getCurrentSession();
  var nextval= session2.createSQLQuery(
     "SELECT nextval('serial')").uniqueResult();
  //print("nextval=" + nextval);
  customer.customerid = nextval;

PostgreSQL 以外のデータベース利用時も、上の SQL 文を(利用するデータベースに)合わせることで対応できます。

アップロード更新を有効にしたモデルの場合

アップロード更新では SessionFactory#getCurrentSession() メソッドは利用できません。そのため、アップロード更新を有効にしたモデルの場合は次のようにスクリプトを修正してください。

  // デフォルトで用意されている session はメインデータベース用です。
  // サブデータベース1 にアクセスするには sessionFactory2 から session を取得して下さい。
  // サブデータベース2 では sessionFactory3 となります。 
  var session2;
  if (SCREENTYPE == "uploadUpdate") {
    // データの INSERT 処理とは別トランザクションとなる。
    session2 = p.appctx.getBean("sessionFactory2").openSession();
  } else {
    session2 = p.appctx.getBean("sessionFactory2").getCurrentSession();
  }
  try {
    var nextval = session2.createSQLQuery(
     "SELECT nextval('serial2')").uniqueResult();
    print("nextval=" + nextval);
    customer.customerid = nextval;
  } finally {
    if (SCREENTYPE == "uploadUpdate") {
      session2.close();
    }
  }

openSession で開いた Hiberate Session は、必ず close するようにしてください。

例 MySQLのAUTO_INCREMENTを利用する

Wagby で MySQL を利用する場合、AUTO_INCREMENT 機能による採番方式は使いません。代わりに「順序値を保持する管理テーブル」を用意し、このテーブルから順序を取得するようにしています。

しかしサブデータベースで MySQL を利用し、かつ既存テーブルが AUTO_INCREMENT を有効にしている場合、Wagby にこの機能を認識させる必要があります。ここではこの方法を説明します。

MySQL が提供する AUTO_INCREMENT 機能は次のような特徴があります。

  • CREATE TABLE 時に主キーカラムに AUTO_INCREMENT の指定を行う。
  • 該当カラムが NULL または 0 の時に自動的に数値がセットされる。
  • セットされる値は1ずつ増加する連番となる。

問題点

既存テーブルに AUTO_INCREMENT の指定がある場合、Wagby では主キーを何もセットしなければ(0となるので)、自動的に採番されます。 しかし Wagby では、ここで採番された主キーの値を知る方法がないため、データ登録後の詳細画面の遷移に失敗し、「対象データは既に削除されているか、対象データを閲覧する権限がありません。」というエラーメッセージが表示されてしまいます。

対応方法

Wagby が生成する <モデルID>.hbml.xml ファイル (Hibernate 用のマッピングファイル)をカスタマイズします。 customer モデルの customerid 項目のカスタマイズ例は次のようになります。

customer.hbm.xml

   ...
   <class name="Customer" table=""customer"">
        <id name="customerid_">
            <column name=""customerid""/>
            <generator class="identity"/> 
        </id>
   ...

上にあるように generator 要素を追加してください。修正したファイルを customize/webapp/WEB-INF/classes フォルダに配置することでビルド時にこの(修正)ファイルが使われるようになります。

Hibernate マッピングファイルをカスタマイズした場合、その後の項目の追加や変更に応じて、開発者が常に同期をとるようにしてください。
LAST_INSERT_ID() 関数を利用して AUTO_INCREMENT の値を取得する方法もありますが、これは接続毎の値の管理となるので、他のシステムからデータの登録が行われた場合の主キーの増加分は LAST_INSERT_ID() に反映されないという問題があります。
MySQL の AUTO_INCREMENT 機能は、ここで説明したように採番された値の取得が行いにくいことから、利用については一長一短があります。Wagby ではこの機能は採用せず、独自の管理テーブルで順序値を保持しています。この方法はスクリプトでこの管理テーブルへアクセスする SQL を実行することで現在の順序値を取得できるというメリットもあります。