本腰入れてActiveObjects(その3) ActiveObjectsを使ってEntityを作成する。それと@NotNullとか@Defaultとか、それと@Generator

今回は「ActiveObjectsを使ってEntityを作成するには」と言う事で前回先に取り上げておけば、と思ったEntityManager#create(RawEntity,DBParam...)辺りをば。
と言っても、こいつはJavaDoc見ればワカンジャンっていうくらいのものですね。DBに実際にINSERT文を発行してEntityをつくります。EntityManager#create(RawEntity,Map)っていうのもありますが、これは中でMapからDBParamsを作ってEntityManager#create(RawEntity,DBParam...)を呼び出すだけです。わかりやすい。
で、実際にDBにレコードをつくろうとかなると、デフォルト値やらNotNull制約やらつけたくなりますよね。そんなときはアノテーションが@Defaultとか、@NotNullとか。その辺の制約をつけたい場合はカラムに対応するアクセッサにこの辺のアノテーションをつけてください。
デフォルト値としてUUIDをつけたいとか、初期値の設定になんらかの処理が必要な場合に使うのが@Generatorです。@Generatorは引数にValueGeneratorインターフェースを実装して使うらしい。こんな感じ。

/** Person.class */
public interface Person extends Entity{
... 中略
	@NotNull
	@Generator(UUIDValueGenerator.class)
	public void setUUID(String uuid); // Stringなのは、DBにUUID型に対応する型が定義されているとは限らないから
	public String getUUID();
}
/** UUIDValueGenerator.class */
public class UUIDValueGenerator implements ValueGenerator<String> {
	public String generateValue(EntityManager manager) {
		return UUID.randomUUID().toString(); // managerを使うのはDBから取得した値を使う場合とか?いろいろできちゃいそうだけど、やると首締めるね。きっと。
	}
}

で、EntityManager#get(Class>,K key...)について。これ、二つめ以降の引数で指定できるkeyは、RawEntityのGenericsの型、つまりPKを指定します。Entityを継承している場合は、整数(intかinteger)を指定しますが、DBに存在しない値を指定したらどうなるでしょう?ちゃんとJavaDocに書いてます。

No checks are performed to ensure that the key actually exists in the database for the specified object.Thus, this method is solely a Java memory state modifying method. There is no database access involved. The upshot of this is that the method is very very fast. The flip side of course is that one could conceivably maintain entities which reference non-existant database rows.

私的訳

渡されたPKが本当にDBに存在するかはチェックしません。したがって、このメソッドはJavaのメモリ上の状態だけ更新します。そしてDBへのアクセスは実行されません。なので、このメソッドを用いて取得したオブジェクトがDBに存在しない場合、このオブジェクトの処理はとてもとても早く実行されます。この事を裏返せば存在しないデータベースの行を参照しているともいえるでしょう。

言っている事はややこしいんですが、要するにDBを用意しなくてもEntityの振る舞いをテストできるということなんです。どういうことか。EntityManager(Class>,K key...)で取得したオブジェクトに値を設定し、その後取得すると、@Implementationで定義した振る舞いも実行されます。(ただ取得だけするとDBから取得しようとするのでアウト)また、テスト用のモックを作成しないでも値を設定して使えるということで、DBのセットアップをする必要がないんです。あんまりそんなフレームワークを知らなかったので、これ変態だと思ったんす。どうすかね。
次回はオブジェクト同士の関連の記述方法辺りをば。