私は次のクラスを持っています:
import play.db.ebean.Model;
import javax.persistence.*;
@Entity
public class A extends Model {
@Id
private int id;
/* Other irrelevant properties */
@OneToOne(cascade = CascadeType.ALL, optional = true)
private B b;
}
import play.db.ebean.Model;
import javax.persistence.*;
@Entity
public class B extends Model {
@Id
private int id;
/* Other irrelevant properties */
@OneToOne(mappedBy = "b")
private A a;
@OneToOne(cascade = CascadeType.ALL, optional = false)
private C c;
}
import play.db.ebean.Model;
import javax.persistence.*;
@Entity
public class C extends Model {
@Id
private int id;
/* Other irrelevant properties */
@OneToOne(mappedBy = "c")
private B B;
}
データベースでは、次のようになります。
Table a
Columns id, ... (other irrelevant columns), b_id
Table b
Columns id, ...(other irrelevant columns), c_id
Table c
Columns id, ...(other irrelevant columns)
ここで、コントローラーメソッド(Playに精通している人向け)の1つに、Aのオブジェクトがあり、そのプロパティ「b」をデータベースから削除したいと思います。これもcにカスケードする必要があるため、cも削除されます。これが私の現在のアプローチです。
B b = a.getB();
b.delete();
ただし、これは例外をスローします。
[PersistenceException:エラー実行中のDML bindLog []エラー[親行を削除または更新できません:外部キー制約が失敗します(
databasename
。a
、CONSTRAINTfk_a_payme_4
FOREIGN KEY(b_id
)REFERENCESb
(id
))]]
基本的には、bを削除しようとしているという事実に要約されますが、aはまだ列b_idにbへの外部キー参照を保持しているため、最初にその参照をnullに設定する必要があります。
Javaでは、これは次のように変換されます。
B b = a.getB();
a.setB(null);
a.update();
b.delete();
これにより、オブジェクトaのbへの参照がnullに設定され、bオブジェクトが正しく削除されますが、cはデータベースから削除されません。(なぜですか?カスケードプロパティがこれを処理しますが)これを修正するために私が見つけた唯一の方法は、cも明示的に削除することです。
B b = a.getB();
C c = b.getC();
b.setC(null);
b.update();
c.delete();
a.setB(null);
a.update();
b.delete();
ただし、データベース内の2つの行を削除するためのコードはすでに8行あるため、これについてはあまり満足していません。この図にもっと多くの関係があればもっと多くなるでしょう。
だから私の質問については:
aからbを削除して、aからbへの参照が最初に自動的に削除されるようにするにはどうすればよいですか?また、bを削除するときにcも削除されるようにするにはどうすればよいですか?
前もって感謝します!
編集:これまでの最良のアイデア:ab関係の所有権をbに移動します。