はじめて投稿します。
杉本と申します。
利用しているのは、
・DBFlute 0.9.6.9
・Java 6
・Seasar2.4
です。
利用しているデータベースをOracle10gからPostgres9.2に変更します。
それにあたり、null・空文字の扱いがDBごとに異なるため
その部分をどう吸収しようか検討しています。
postgresに変わることで null と 空文字があることで、
is null の条件、order by(nulls first) 等への影響があるため
oracleと同じ動き(※1)をさせた方がDB変更による影響が少ないだろうと
思っています。
※1:DB上は空文字を存在させないようにし、nullの状態にしておく。
そこで考えているのは、
1)
littleAdjustmentMap.dfprop の isEntityConvertEmptyStringToNull をtrueにして
自動生成(generate.bat)を実行してエンティティを再生成することで
convertEmptyToNullでの処理が変わり、空文字ならばnullが返却されるコードが
自動生成されることは確認済です。
再生成されたエンティティを利用すれば、insert/update において 空文字はnullでDBに登録され、
select結果のエンティティもnullになる動作のため、DB変更前のoracleのときと変わらない
使い方ができるのではと思っています。
2)
isEntityConvertEmptyStringToNull =falseのままの場合は、
ImplementedCommonColumnAutoSetupper にて、entityを引数にとるため、そのentityクラスにて
リフレクションを利用して、プロパティの型をチェックして、String(DB上はvarcharやchar)型の場合に、
長さ0の空文字だった場合にentityのプロパティのセッターをリフレクションで呼び出してnullにする
という方法をとろうと思っていますが、他に良い方法はありますでしょうか?
3)
DBFlute関連での対応でなく、SAStrutsを利用しているため、
S2RequestProcessorを拡張してActionFormのインスタンス生成後、Actionクラスへの
ActionFormのインジェクション前後あたりで、リフレクション等でStringのプロパティを
nullに書き換える。
ただ、List<String>、Mapや、配列、ActionFormの中にネストしたクラスがある場合など
考慮する点が多そうなのと、ActionFormのバリデーションが空文字をnullにコンバートした
前や後などどちらにすべきかといったことで、・・・・考慮点が多そうなので、3)は
採用しない方が良いかなと思っています。
なお、外出しのsqlファイルは、修正が必須なので修正します。
例えば、
- NVLからの変更でCOALESCE等の利用
- サブクエリのエイリアス指定の追加
- is null / is not null の条件は空文字が入る場合は、変更が必要だが、DB上で空文字は存在させない。
- 文字列連結の col1 || col2 で、どちらかがnullとなる場合はCOALESCE等の利用して空文字に返還しておく
- Order by での nulls first はOralceもpostgresも同じ挙動だが、空文字が混在すると、
空文字の順序はnullと同じではないため順序が変わる
oracleからpostgresへのデータ移行は、ora2pg というのを使う予定です。
上記の1)と外出しsqlファイルを適宜修正していく方針と思っていますが、
他に良さそうな方法や、DBFluteをつかっていてOracle→postgresに変更した際の対応例など
ありますでしょうか。
よろしくお願いします。