繰り返しコンテナ - 独立したモデルとして扱う

最終更新日: 2022年5月18日
R8 | R9

「見積書」モデルに含まれる繰り返しコンテナ「内訳」を、別モデル「見積明細」として操作できるようにします。 下図のようなイメージです。

繰り返しコンテナはデータベース上は別テーブルとなっており、テーブル名は次のルールで決められています。

モデルID + "$" + 繰り返しコンテナID
繰り返しコンテナを別モデルとして扱うイメージ

見積書モデルの繰り返しコンテナは図2のとおりです。

見積書モデル詳細画面

追加した「見積明細」モデルの検索画面を図3に示します。繰り返しコンテナ部分がデータとして検索できます。
内容は図1と同じです。

見積明細モデル検索・一覧画面

定義方法

  1. 繰り返しコンテナを定義した「見積書」モデルです。
    見積書モデルの定義
  2. 「見積明細」モデルを用意します。ここではまだ項目の定義は行いません。
    見積明細モデル(中身は空)
  3. 見積書から見積明細モデルへ、項目をコピーします。
    「見積書」モデルの定義を開きます。
    繰り返しコンテナ内の項目(繰り返しコンテナ、繰り返しコンテナID項目は除く)を選択し、ギアアイコンから「コピー > 他モデル」をクリックします。
    表示されたダイアログで先ほど用意した「見積明細」モデルを選択し「OK」ボタンをクリックし、コピーします。
    項目のコピー(1)
    項目のコピー(2)

    ワンポイント

    繰り返しコンテナとして用意するモデルと元になるモデルの項目は、詳細定義の内容を揃える必要があります。
    元のモデル(ここでは見積書)と違う設定が入っていると、アプリケーションが正しく動かない可能性があります。
    そのため、ここでは項目のコピー機能を使用しています。

  4. 「見積明細」モデルを開きます。
    見積書から項目がコピーされました。
    項目がコピーされた
  5. 余計な空の項目は削除します。
    コピーした項目は見積明細モデルでは繰り返し項目としないため、項目名の「precord/」を削除します。
    定義のルールは次の通りです。
    • 主キーの項目IDは「見積書」モデルと同じ値にしてください。
      この例では「pkey」です。
    • 項目IDが「繰り返しコンテナ名 + "jshid"」となる数値型(整数)項目を用意してください。
      この例では「precordjshid」です。
    • 「pkey」と「precordjshid」の二つに対して「主キーとして利用する」を有効にし、複合主キーとします。
    • モデル項目は、参照元の繰り返しコンテナと同じ項目ID、同じ型、同じ詳細定義としてください。
      項目名は変更可能です。
    • 参照元の繰り返しコンテナの項目を減らすことはできますが、追加することはできません。
    見積明細モデルの定義
  6. 繰り返しコンテナID「precordjshid」を主キーとして利用する設定を行います。順序は利用しません。
    主キーの設定
  7. 見積明細モデルの「画面 > その他 > データベースの詳細」を開きます。
    「テーブルを作成する」を無効とし、物理テーブル名を「quotation$precord」と設定します。
    さらに「キャッシュを有効にする」を解除します。
    データベースの詳細設定
  8. 「見積明細」モデルは、登録・更新・削除は行わないよう設定します。
    「画面 > 新規登録」と「画面 > 更新」タブ内の「画面を作成する」のチェックを外します。
    このモデルは参照のみで運用することを想定しています。(データ入力は元々の「見積書」モデルで行います)
    新規登録画面を作成しない
    更新画面を作成しない

更新を行いたい場合

上の説明では「更新画面を作成しない」としていますが、その理由は次のとおりです。

  1. 元のモデルと、繰り返しコンテナ独立モデルの双方で更新すると、メモリに保持されているキャッシュの整合性がとれない。
  2. 両方が同時に更新処理を行ったとき、ロックキーが異なるため、ロック機構が働かない。

この問題を回避する方法を紹介します。

キャッシュを使わない

元のモデル(上の例では「見積書」)と、繰り返しコンテナ独立モデル(上の例では「見積明細」)のそれぞれで、キャッシュを無効にします。パフォーマンスは不利になります。

同時に更新されない運用とする

例えば見積書に制御フラグを用意します。このフラグ値によって、一方の更新ボタンを無効にするというボタン表示制御式を用意し、同時更新を回避します。

ロックキーを同じにする

繰り返しコンテナ独立モデル(上の例では「見積明細」)のロックキーを、元のモデル(上の例では「見積書」)に合わせます。この場合、繰り返しコンテナ独立モデルの個々のレコード単位でのロック制御は行えなくなります。(繰り返しコンテナ行全体で、一つのロックキーとなるためです。)

スクリプトで利用する

スクリプトで繰り返しコンテナ独立モデルを操作することができます。WDN

ここでは customer モデルに favorite (趣味) という繰り返しコンテナを用意したとします。また、繰り返しコンテナ独立モデル Favorite を定義したとします。

var Favorite = Java.type("jp.jasminesoft.wagby.model.favorite.Favorite");
var entityService = p.appctx.getBean("FavoriteEntityService");
var key = new Favorite.Key();/*複合キーの扱いになる*/
key.id = 1000;
key.contjshid = 1;
var favorite = entityService.findById(key);
print(favorite);

トラブルシューティング

データインポート時や init_db 実行時に警告が発生する

system.log や initdb.log に次のような警告が出力されることがあります。

Invocation of init method failed; nested exception is org.hibernate.MappingException: Foreign key (...) must have same number of columns as the referenced primary key (...)

このExceptionが発生した場合は、主キーの定義が誤っている可能性があります。主キーの定義の見直しを行って下さい。