DBFluteのぶり対応をカスタマイズ
jfluteさん向けメモ的なエントリ。
DBFluteでぶり対応を有効にすると、Entityに「BuriDef.パッケージ_プロセス_Status getStatus_パッケージ_プロセス()」というメソッドが追加されるけど、メソッドの中で getBuriPathData().getPathName() をしている。この「getBuriPathData()」を「getBuriPathHistoryDataUser()」にするのが今回の話。
BuriPathDataはParticipantProviderを使わない場合に利用するビューであって、ParticipantProviderを使ってアプリ側の実行ユーザー情報をBuriStateUserテーブルに入れている場合、そのユーザー情報も含めて取得するにはBuriPathDataUserビューを使わないといけない。
さらに、BuriPathDataUserには、INSERTDATE(その状態になったTimestamp)属性が無い。そのため、アプリの要件で「現在の状態と、その状態にしたユーザーと、その状態になったタイムスタンプ」を出そうとすると、BuriPathDataUserでも情報が足りない。この要件を満たすには、最新のBuriPathHistoryDataUserを取得しなければならない。
とりあえず、今回は必ずParticipantProviderを使うので、暫定でEntityにBuriPathHistoryDataUserへのadditionalForeignKeyを設定して、BaseEntity.vmのgetStatus_XXXで、getBuriPathDataしてるとこをgetBuriPathHistoryDataUserにしました。additionalForeignKey.dfpropはこんな感じに。
; FK_MEMBER_BuriPathHistoryDataUser = map:{ ; localTableName = MEMBER ; foreignTableName = BuriPathHistoryDataUser ; localColumnName = MEMBER_ID ; foreignColumnName = pkeyNum ; fixedCondition = $$foreignAlias$$.dataType = 'example.exentity.Member' AND $$foreignAlias$$.processDate > CURRENT_TIMESTAMP ; fixedSuffix = AsLatest }
普通、BuriPathHistoryDataUserはEntityとN:1なんだけど、processDate > CURRENT_TIMESTAMP を入れることで1:1の関連にした。(CURRENT_DATEだとINSERTしてSELECTするテストコードで同じ秒の物を2件取得しちゃってコケる)
BaseEntity.vmはこんな感じ。
Index: dbflute/mydbflute/dbflute-0.9.4.1/templates/om/java/bsentity/BaseEntity.vm =================================================================== --- dbflute/mydbflute/dbflute-0.9.4.1/templates/om/java/bsentity/BaseEntity.vm (revision 1923) +++ dbflute/mydbflute/dbflute-0.9.4.1/templates/om/java/bsentity/BaseEntity.vm (working copy) @@ -419,8 +419,8 @@ // ============== #foreach ($processName in $table.tableProcessForMethodNameList) public ${glBuriDef}.${processName}_Status getStatus_${processName}() { - if (getBuriPathData() == null) { return null; } - return ${glBuriDef}.${processName}_Status.codeOf(getBuriPathData().getPathName()); + if (getBuriPathHistoryDataUserAsLatest() == null) { return null; } + return ${glBuriDef}.${processName}_Status.codeOf(getBuriPathHistoryDataUserAsLatest().getPathName()); } #end #end
現在の状態を取得するとか、〜状態にあるエンティティを取得するだけならBuriPathDataで事足りるけど、それ以外のことをやろうとすると必ず他のビューが必要になるので、DBFluteが対応してるやつ以外にも自分でadditionalForeignKeyを追加する必要がありそう。ただBuriPathHistoryDataUserからMEMBERにadditionalForeignKey張ろうとしたら、pkeyNumがLong型、EntityのPKがInteger型で、コンパイルエラーになっちゃう。。。