Şimdi işe deneme amaçlı bir entity sınıfı yazarak başlayayım ve jpa daki default inheritance türü olan SINGLE TABLE ı incelemeye başlayalım.
AbstractEntity sınıfı
package Entities;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name="Abstract_Entity")
@Entity
public class AbstractEntity implements java.io.Serializable {
@Id
private Long id;
private String commonAttribute;
public String getCommonAttribute() {
return commonAttribute;
}
public void setCommonAttribute(String commonAttribute) {
this.commonAttribute = commonAttribute;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
yukarıda basit bir sınıf yarattım, bu sınıf diğer sınıfların “extend” edeceği, super sınıf. Annotation’larla default değer değiştirilmediyse jpa nın kullanacağı inheritance strategisi single table, şimdi diğer alt sınıfları da yaratalım.
package Entities; import java.util.ArrayList; import java.util.List; import javax.persistence.Entity; import javax.persistence.OneToMany; @Entity public class ATypeEntity extends AbstractEntity implements java.io.Serializable{ @OneToMany private List attributes = new ArrayList() {}; public List getAttributes() { return attributes; } public void setAttributes(List attributes) { this.attributes = attributes; } } package Entities; import javax.persistence.Entity; @Entity public class BTypeEntity extends AbstractEntity implements java.io.Serializable{ private int bTypeEntityAttribute; public int getBTypeEntityAttribute() { return bTypeEntityAttribute; } public void setBTypeEntityAttribute(int bTypeEntityAttribute) { this.bTypeEntityAttribute = bTypeEntityAttribute; } }
package Entities; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class AttributeEntity implements java.io.Serializable { @Id private Long id; private String attribute; public String getAttribute() { return attribute; } public void setAttribute(String attribute) { this.attribute = attribute; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
ATypeEntity ile BTypeEntity AbstractEntity sınıfından türetildiler, yani AbstractEntity nin id ve commonAttribute değişkenleri her ikisinde de var. ATypeEntity nin bunun yanında one to many bir ilişkisi var, BTypeEntity nin ise kendine özel bTypeEntityAttribute adında bir değişkeni var.
Single Table stratejisinden beklediklerim!
Tüm bu ilişkileri tek bir tabloda toplamalı
Tablo içinde bir sütunla tablodaki satır’ın hangi objeye ait olduğunu söylemeli
- Tüm sınıflar aynı tabloda tutulduğu için mesela BTypeEntity e ait bir değişken, ATypeEntity e ait bir satırda boş bırakılmalı.
Yukarıda tam istediğim şekilde database yapısını oluşturdu. Bir kaç değer girdiğimde ise Dtype sütunun satırın ait olduğu objenin sınıfını belirtmek için kullanıldığını, diğer alanların ise boş kaldığını gördüm, böylece “single table” aslında tam beklediğim gibi çalısıyor.
Şimdi biraz bu strateginin avantajları dezavantajları üzerinde düşünelim,
Buradaki en büyük dezavantaj sınıfların sahip olmadıkları değişkenler içinde database de yer tutmaları ayrıca database deki satırların büyük boyutlu olması da iyi birşey değil. Ama yine de bu yöntem gayet basit ve tek satırla tüm bilgi alınabiliyor.
Not nullable sütunlar kavramıEğer her sınıfın değişkenleri tek tabloda tutuluyorsa, bir sınıf kendisine ait olmayan değişkenleri null yani boş olarak bırakıyor, bu durumda “not nullable” yani boş bırakılamaz değişkenler tanıtamıyoruz çünkü diğer bir sınıf kendisine ait olmayan bu değişken için “null” olarak tabloya girecek.
Simdi ikinci yönteme geçelim, “JOINED”
Burada yöntemimizi değiştirebilmek için tek yapmamız gereken, AbstractEntity sınıfına @Inheritance annotation ı ile strategimizi değiştirmek.
package Entities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; @Table(name="Abstract_Entity") @Entity @Inheritance(strategy=InheritanceType.JOINED) public class AbstractEntity implements java.io.Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String commonAttribute; public String getCommonAttribute() { return commonAttribute; } public void setCommonAttribute(String commonAttribute) { this.commonAttribute = commonAttribute; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
Şimdi benim JOINED strategisinden beklediklerim,
- Her sınıfın ayrı bir tablosu olacak
- Her sınıfın ayrı tablosunda sadece kendisiyle ilgili değişkenler tutulacak
- Tablolar kendi aralarında JOIN sütunuyla ilişkilendirilecek.
Resimden görüldüğü gibi her sınıfın ayrı tabloları oluşmuş ve her tablo kendi sınıfıyla ilgili değişkenleri tutuyor. Bu yapıda mesela ATypeEntity sınıfına ait bir obje istendiğinde, AbstractEntity ve ATypeEntity e ait tablolar aralarında join yaparak bu obje oluşturulacaktır.
Bence bu yöntem object oriented mantığına daha çok uymakta, fakat her obje için join yapılmakta, eğer sınıflar arasında fark fazlaysa bence bu yöntem ilk yöntemimiz olan “single table” a göre daha uygun. Fakat her obje için sorgunun maliyeti joinlerden dolayı biraz fazla.
JPA nın inheritance için sunduğu son yöntem ise “Table Per Class” yani Türkçesiyle her sınıf için bir tablo. Bu yöntemden beklediklerim,
- Tüm sınıfların ayrı tablosu olması fakat ayrıca bir sınıfa ait bir tablonun türediği sınıfa ait olup kendisine geçen değişkenler içinde yer tutmasıdır.
package Entities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; @Table(name="Abstract_Entity") @Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public abstract class AbstractEntity implements java.io.Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String commonAttribute; public String getCommonAttribute() { return commonAttribute; } public void setCommonAttribute(String commonAttribute) { this.commonAttribute = commonAttribute; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
Table per class inheritance is not supported. Entity class [class Entities.AbstractEntity]. Hatasını alıyorum. Bu mesaj bana toplink in “table_per_class” ı desteklemediği izlenimine kapılıyorum. Yazımı burada sonlandırıyorum, çünkü elimde toplink ten başka jpa implementasyon paketi yok ve sorularım cevapsız kalıyor ne yazık ki.
Yaziniz icin cok tesekkur ederim. cok faydali oldu
YanıtlaSil