AppEngineでは、データがapplicationIdを持っています
Google App Engine for Javaで
hogeというIDのアプリケーションで作成したデータを、
fugaというIDのアプリケーションに投入にするには?
bulkloader ですよね。
Appengine Bulkloader IO 2010
自分はAppEngineは、Javaのほうを使っているんですが、
このbulkloader(appcfg.py)は便利に使っています。*1
・・・が、ちょっとつまづいたのでメモ。
hugaアプリケーションで動作確認をしたら、
こんなエラーメッセージを出されました。
app fuga cannot access app hoge's dataえー?データがアプリケーションID持っているんだっけ?
はい、そうみたいです。
参考リンク:
BadRequestError: app * cannot access app * data
そしてアプリケーションIDをまたいでデータを移す場合には、
bulkloader がそのへんよろしくやってくれているとのこと。
ふむふむ確かに、いままで開発中さんざんbulkloaderを使ってきたけど、
ふつうにアプリケーションIDをまたいでデータを使い回せていた。
で、自分のソースコードを改めてよくみてみると、
a) エンティティFoo が、別のエンティティBar の実体を、プロパティとしてまるごと保持している。Bar のKeyも込みで。
b) その、保持されるエンティティBar が、また別なエンティティへの外部キーを複数、リストプロパティで保持している。
うんうん、これはだめだろうな。いかにbulkloaderといえどもシリアライズされたBlobなデータをひもといて
アプリケーションIDのケアしてくれるわけないよね。
さて、どう直すべきか。
この、エンティティBar は、いちおうDatastore上に永続化されるんですが、
いわばセッション的な使い捨てデータです。
ただ、エンティティFoo に関連付けられた場合は、永続すべき価値を持つ、というものなんです。
なので、
- エンティティFoo がエンティティBar の実体をプロパティとして保持するのをやめて
- エンティティBaz という、Barとインターフェースを同じくするクラスのを作って、Barの値はこっちに移したうえで永続化する。
- エンティティFoo はBaz への参照(Slim3のModelRef)を保持する
が
うーーむ。要はRDB的にしたっていうことか。なんか爽快感がないな。
いちトランザクションで永続化するエンティティBaz が増えたので、
つまりSlim3のグローバルトランザクションの参加メンバーが増えてしまったしね。
というか、最初の実装が駄目であることにいまひとつ納得がいかない。
いずれにせよ、「Keyを含むBlobデータには注意すべし」ですね。
※探したら、ほかにこんなフィールドをモデルクラスに持たせていました。これも、別な方法で修正しました。
@Attribute(lob = true)
private Map
*1:namespaceは、未定義です。