19 Ekim 2023 Perşembe

JPA @OneToMany İlişki - Bidirectional Join Tablosu Olmadan

Giriş
Eğer join tablosu olmasın istiyorsak parent tarafında OneToMany ve mappedBy, child tarafında ise ManyToOne ve JoinColumn birlikte kullanılır. Bu normal kullanım ve performanslı

Parent mappedBy="..." ile karşı sınıftaki attribute ismini belirtir. Child ise JoinColumn ile kendi tablosunda hangi sütunun foreign key olarak kullanılacağını belirtir.

Veri tabanına önce parent kaydedilir. Parent'ın PK değeri, child tabloda FK olarak kullanılır.

Bu ilişkide genellikle parent nesne silinirse child nesneler de otomatik olarak silinir. Parent'ı silip child nesneyi saklama yapılmaz. Yani genellikle şu anotasyon ile kullanılır
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
Eğer orphanRemoval = true değilse sadece parent'ı silmeye çalışırsak foreign key ile ilgili bir hata alırız.

Örnek
Şöyle yaparız. Burada orphanRemoval = true değil yani ufak bir eksiklik var.
@Entity
@Table(name = "OWNER_DETAILS")
public class Owner {
    
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "ID")
  private int id;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", cascade = CascadeType.ALL)
  private List<Blog> blogList;
  ...
}

@Entity
@Table(name = "BLOG_DETAILS")
public class Blog {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "ID")
  private int id;
  
  @ManyToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "owner_id")
  private Owner owner;
  ...
}
Tablolar şöyle. Child tarafında owner_id isimli sütun görülebilir


Örnek
Şöyle yaparız. Burada orphanRemoval = true değil yani ufak bir eksiklik var.
@Entity
public class Company {
  @OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
  private List<Branch> branches;
}

@Entity
public class Branch {
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "companyId")
  private Company company;
}
Örnek
Parent tarafında şöyle yaparız.
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<Product> product = new ArrayList<Product>();
Child tarafında şöyle yaparız.
@ManyToOne
@JoinColumn(name = "product_Id", referencedColumnName = "product_Id", nullable = false,
  insertable = false, updatable = false)
private Order order;

Hiç yorum yok:

Yorum Gönder