Domaでvarcharとnvarcharを使い分けたい場合
ちょっとトリッキーな方法ですが、ドメインクラスを使うとできます。まずは利用イメージを示します。
エンティティはこんな感じで、varcharをString、nvarcharをNStringにマッピングするものとします。NStringはもちろんこれから自作するクラスです。
@Entity public class Person { public String name; public NString name2; }
NStringはStringと相互に変換可能で、こんな風に使えます。
Person person = new Person(); person.name2 = NString.of("あいう"); String name2AsString = person.name2.getValue();
使うのはたぶん難しくない。
で、ここからが本題の実現方法の説明です。まずはnvarcharにマッピングするNStringクラスを作ります。DomainアノテーションのvalueType要素には、アプリの他の箇所で使わない型を指定するのがポイント。この例ではjava.sql.Arrayを使います。この例のArrayに相当する型は単なるダミーです。Stringと相互変換できて他の箇所で使っていなければなんでもOKです。
@Domain(valueType = Array.class, accessorMethod = "getAsArray") public class NString { private final ArrayImpl value; // package private NString(Array value) { this.value = (ArrayImpl) value; } // package private Array getAsArray() { return this.value; } public String getValue() { return value.getValue(); } public static NString of(String value) { return new NString(new ArrayImpl(value)); } public static class ArrayImpl implements Array { private final String value; public ArrayImpl(String value) { this.value = value; } public String getValue() { return value; } // ログ出力で呼び出される @Override public String toString() { return value; } // あとはArrayの実装メソッドがつづく、どれも呼び出さないので適当に例外をスローしておいてください ... } }
次に使いたいDB(この例ではSQL Server 2008)のDialectに対応するJdbcMappingVisitorを継承して次のように記述します。何をしているかというと、ダミーのArrayとStringの相互変換。それから、JdbcTypes.NSTRINGを使ってStringとnvarcharの相互変換ができるようにしています。
public class MyJdbcMappingVisitor extends Mssql2008JdbcMappingVisitor { @Override public Void visitArrayWrapper(ArrayWrapper wrapper, JdbcMappingFunction p) throws SQLException { StringWrapper stringWrapper = new StringWrapper(); ArrayImpl array = (ArrayImpl) wrapper.get(); if (array != null) { stringWrapper.set(array.getValue()); } p.apply(stringWrapper, JdbcTypes.NSTRING); wrapper.set(new ArrayImpl(stringWrapper.get())); return null; } }
最後に、ConfigクラスのDialectの設定の際、コンストラクタで上記のJdbcMappingVisitorのインスタンスを渡します。
private static final Dialect dialect = new Mssql2008Dialect(new MyJdbcMappingVisitor());
ログ出力もカスタマイズしたいということであれば同じ要領でSqlLogFormattingVisitorを継承して出力を調整できます。