削除機能を実装するために

Cayenneにおいて、データベースからデータを削除する事は非常に簡単です。
ただし、リレーションを張っている場合は注意する必要があります・・・って、これはリレーショナルデータベースを扱っていたら当たり前な事なんですけどね。

実際に削除するためには、やはりDataContextをいじります。

context.deleteObject(message);
context.commitChanges();

このように、削除対象のオブジェクトを引数にとったdeleteObjectメソッドを呼んでやり、最後にコミットするだけです。
しかし、先ほど書いたように、リレーションを張っている場合、この掲示板のケースだと削除対象が親メッセージの場合に注意を払う必要があります。


仮に何も考えず、メッセージを削除したと考えます。
そうすると、削除されたメッセージに子供(childrenリレーション)があった場合、それらはみな孤児になってしまいます。
したがって、親を消した時は、子も一緒に消さなければなりません。(現実世界ではあってはならない事ですが!)
そのような問題を、Cayenneではどうやって解決しているのでしょうか??答えは実に簡単で、データベースにおまかせという訳です(笑)。


一般的に手動でスキーマ定義をする場合、リレーションがあればCONSTRAINT句で制約を付けると思います。CayenneではそのSQLCayenne Modelerが自動で発行してくれるという訳です。

ただし、Modeler上で以下の設定をやらなければなりません。


Messageのchildrenリレーションの設定で、Delete RuleにCascadeを選択します。デフォルトではNo Actionですので、ご注意下さい。


そうすると、以下のようなSQLを作ってくれます。

ALTER TABLE message ADD CONSTRAINT C_message_12460778 FOREIGN KEY (p_id) REFERENCES message (id) ON DELETE CASCADE;

実行環境や使うDBによって多少変わってくるとは思いますが、大体似たようなものだと思います。

ON DELETE CASCADE

がしっかり発行されているともいます。