GAE/Jでカスケードデリートができない!! (Please help!! Cascade delete doesn't work on GAE Data Store.)

Google Apps Engine(GAE)でよく言われるのが、「データストアが…」ということ。

公式HPによれば、JDO2.3、JPA1.0をサポートと言われているが、確かに制限事項が多くて、「なにが使えるのか」分からない。

  • Joinが使えない。
  • 非所有関係がサポートされていない。
  • eager loadがサポートされていない。
  • 「1つのトランザクションは1つのエンティティーグループ内」という制限がある。

とかとか、「使えない機能」はボツボツ出てくるのだが、「何が使えるの?(=こうしたいんだけど、どうやったらいいの?)」については「やってみないとわからない」というところだろうか?

データストア(Big Table)はリレーショナルデータベース(RDB)ではない」といいつつ、エンティティー=レコード、エンティティー=テーブル、プロパティー=カラムなどというRDBのアナロジーで説明する記事を読んだりする。
実際、上のアナロジーは正しくなくて、強いていれば、エンティティー=レコード、カインド(種類)=テーブル、プロパティー=カラムというべき。
エンティティーグループは、エンティティーの階層構造を表す概念。この階層構造は、エンティティーの主キーに「ルートからのパス」として("/"で区切られて)表現される。日本語の公式HPで「種類」と訳されているのは、このカインド(kind)のことで、エンティティー名(クラス名)が採用される。

このエンティティー・グループの他に、一般のデータモデルでいうところの「所有」という「関係」が定義される。所有は、上述の階層構造でいえば「所有者の1つ下位に被所有者を置く」ということ。つまり、所有関係も、エンティティーグループのパスの概念に帰着されている

非所有の関係とは、(所有関係をもたない)いわゆる「外部キー」だが、この機能は実装されておらず(joinも実装されておらず)、エンティティーに「外部キーにあたるもの」を保管して、各々管理せよ、となっている。

さて、「所有」に話を戻すと、被所有のエンティティーは、「親(所有者のエンティティー)の主キー情報を含む主キー」を持てばいいことになる。
だから、まず、所有者のエンティティーを作成して、そのプロパティーの1つに被所有のエンティティーをset、PersistenceManagerのmakePersistence("所有者のエンティティー")すれば、所有者のエンティティーと、被所有者のエンティティー2つがストアされる。各々の主キーも、見たところ問題なく、ルートからのパスが自動的に設定される。

ここで、つまづいてしまった

「所有」の関係ができる、ということは、所有者エンティティーの削除にあわせて、(自動的に)被所有者のエンティティーも削除される、カスケード・デリート(リカーシブ・デリート)ができるということだ。
HPでも、そのように説明されている。

だが、これができないーーー。deletePersistent("所有者")としても、被所有者がしっかり残ってしまう

(HPにあるように)被所有者にmapped by属性をもたせても(こうすると、双方向の関係ができてしまうので、本意ではないのだが)、javax.persistenceのアノテーション(OneToOneとか)を引っ張り出してきても消えない。

うーーーん、と唸ってしまった。

本当にできるのか??
ググって見ると「できるような」記事があったりするので、できそうな気もする。
もしかしたら、「おまじない」みたいなものがあるかもしれない。

ソースコードがグチャグチャなので、整理してからUpしたい。