Closed1

SpringDataJPAの双方向関係のOneToOneの子供の削除について

naouminaoumi

参考

Java Persistence API 2.1のおさらいメモ

親と子供のコード

@Entity
@Table(name = "parent")
public class Parent {
  @Id
  private String id;

  // 子供に対する外部キー
  // "orphanRemoval = true"を設定することによって、子供が削除されても、親は削除されない
  @OneToOne(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
  private Child child;

  public  getChild(){
    return this.child;
  }

  public  setChild(Child child){
    this.child = child;
  }
}

子供

@Entity
@Table(name = "child")
public class Child {
  @Id
  private String id;

  // line_accountsテーブルに対する外部キー
  // "fetch = FetchType.LAZY"を設定することによって、親を介さずに子供のデータを直接操作できる
  @OneToOne(fetch = FetchType.LAZY)
  @JoinColumn(nullable = false)
  private Parent parent;
}

正しい子供のデータの削除のやり方

// 子供のインスタンスを取得する
var child = parent.getChild();

// 親から子供の関係を先に削除する(DBに反映せずに、インスタンスのプロパティの削除だけでOK)
child.setChild(null);

// 子供のデータを直接削除する
childRepository.deleteById(child.getId());

削除されないやり方

この場合、エラー自体発生せずに削除に失敗する。
理由は、親から見て、子供の存在がまだあるため、整合性を取るために削除されない。
なぜエラーを吐かないのかは分からない。

// 子供のインスタンスを取得する
var child = parent.getChild();

// 子親から子供の関係を先に削除せずに、子供のデータを直接削除する
childRepository.deleteById(child.getId());
このスクラップは2022/01/12にクローズされました