SiNBLOG

140文字に入らないことを、極稀に書くBlog

Slim3 Source Code Reading #3に参加してきた!

Slim3 Source Code Reading #3 - ChugokuGTUG

に参加してきました。

今回は、Datastore.get()を読み進めて行ったのですが、一番盛り上がった(はまった?)
のは、以下の部分。

ModelMeta#validateKey()


protected void validateKey(Key key) throws IllegalArgumentException {
if (key != null && !key.getKind().equals(kind)) {
throw new IllegalArgumentException("The kind("
+ key.getKind()
+ ") of the key("
+ key
+ ") must be "
+ kind
+ ".");
}
}


DatastoreUtil#entityMapToModelMap()などから呼ばれています。


public static Map entityMapToModelMap(ModelMeta modelMeta,
Map map) throws NullPointerException {
if (modelMeta == null) {
throw new NullPointerException(
"The modelMeta parameter must not be null.");
}
if (map == null) {
throw new NullPointerException(
"The map parameter must not be null.");
}
Map modelMap = new HashMap(map.size());
for (Key key : map.keySet()) {
Entity entity = map.get(key);
ModelMeta mm = getModelMeta(modelMeta, entity);
mm.validateKey(key);
M model = mm.entityToModel(entity);
mm.postGet(model);
modelMap.put(key, model);
}
return modelMap;
}


ここで以下の疑問が出ました。
GetしたEntityのKeyのKindが間違っていることなんかあるの?

確かにKeyを指定してGetしたのに、違うKindがEntityが来る可能性があるとすれば驚きです。
しかし、色々と考えていると、以下のようなパターンのためだと分かりました。


Key key = Datastore.createKey(HogeModel.class, 1);
FugaModel fuga = Datastore.get(FugaModel.class, key);

上記の例だとKeyはHogeModelのものですが、Datastore#get()の第1引数には、FugaModelを渡しています。
この場合、ModelMeta#validateKey()でエラーとなります。


また、Modelのフィールドとして、他のModelのKeyを持っている場合、
Datastoreに格納されているものの中に、想定しているModelのKeyでは無いものが
あるかもしれません。
そのような時もvalidateKey()でエラーとなるようにしているのでしょう。

ModelのフィールドのKeyをタイプセーフにしたい場合は、リレーションシップを使うと良いのでしょうね。
リレーションシップ - Slim3 日本語サイト(非公式)


次回はTransaction周りを読んでいこうという話でしたが、
時間があれば、リレーションシップ周りも読んでみたいですね。