Hibernate’de sınıflar arası ilişkileri incelediğimiz yazı dizimizin ilk bölümü nden sonra ikinci bölüm ile devam ediyoruz. Bu bölümde M:1 ilişkiler üzerinde duracağız.
M:1 ilişkiler entity-entity veya component-entity şeklinde olabilir. Fakat target sınıfın component yani “Embeddable” olması mümkün değildir. Çünkü herhangi bir bileşenin ancak ve ancak tek bir sahibi olabilir. Birden fazla entity instance’ın ortak bir bileşene refer etmesi mümkün değildir.
entity-entity arasında tek yönlü M:1 ilişki kurmak için @ManyToOne
annotasyonu kullanılır. İlişkinin zorunlu olup
olmadığı optional
attribute ile gösterilir. İlişki veritabanında join cloumn veya join table üzerinden yönetilebilir.
Join column üzerinden yönetmek için @JoinColumn
annotasyonu kullanılır. nullable
attribute ile foreign key’in
NULL/NOT NULL olup olmadığı belirtilebilir. optional
attribute ilişkinin zorunluluğunu, nullable
attribute ise
foreign key’in null olup olmayacağını belirlemesine rağmen, mevcut hibernate sürümlerinde her ikisinden birisinin
ilişkinin zorunlu olduğunu belirten bir değer alması üretilen DDL ifadesinde foreign key sütununun da NOT NULL olmasını
sağlamaktadır. Konu ile ilgili 4.x sürümleri için açık bir bug mevcuttur.
Optional attribute’un önemi M:1 ilişkinin @JoinTable
ile map edilmesinde ortaya çıkar. optional=false
olarak işaretlenmiş
bir M:1 ilişkiye sahip bir entity persist edilmek istendiğinde Hibernate ilişkinin değerinin olmadığını tespit ederek daha
SQL ifadesi çalıştırmadan org.hibernate.PropertyValueException: not-null property references a null or transient value
hatası üretir. Hibernate 4.x sürümlerinde ilişki @JoinTable
ile map edilmiş ise malesef property değerinin null olup
olmadığı kontrol edilmeden entity DB’de persist edilmesine neden olan bir bug mevcuttur. Veri modeli açısından herhangi
bir tutarsızlık söz konusu olmamasına rağmen Hibernate metadatasında zorunlu olduğu söylenen bir ilişkiye sahip olmadan
entity instance’ının persist edilmesi doğru değildir. Bu bug 4.1.12‘de fix’lenmiştir.
Tablolar arası ilişkileri yönetmek için kullanılan join table yönteminde dikkat edilmesi gereken temel nokta @JoinTable
annotasyonundaki joinColumns
ve inverseJoinColumns
attribute’larının değerleridir. JoinColumns
source entity’nin PK
sütunlarına, inverseJoinColumns
ise target entity’nin PK sütunlarına foreign key ilişkiler kurmalıdır.
Tek yönlü ilişkilerde component-entity için de M:1 ilişkilerin kurulması mümkündür. Buradaki tanımlama da aynen entity-entity M:1 ilişkilerinde olduğu gibidir.
Çift yönlü M:1 ilişkilerde ise ilişkinin diğer tarafı 1:M olarak ele alınmaktadır. 1:M ilişkili entity’lerin tutulduğu
collection’ın List
olmadığı durumlarda çift yönlü ilişkiyi yöneten genellikle M:1 tarafı olarak belirtilir. Bunun için
@OneToMany
annotasyonundaki mappedBy
attribute’u kullanılır. 1:M ilişkileri inceleyeceğimiz bir sonraki yazımızda
@OneToMany
annotasyonu üzerinde ayrıntılı biçimde duracağız.
@ManyToOne
annotasyonu mappedBy
attribute’una sahip değildir. Dolayısı ile çift yönlü ilişkilerde M:1 tarafını
ilişkiyi yöneten taraf yapmamak için farklı bir yol izlenmektedir. Çift yönlü ilişkilerde M:1 tarafını salt okunur yapmak
için @JoinColumn
annotasyonunun insertable
, updateable
attribute’ları kullanılmaktadır. insertable=false
ve
updateable=false
olarak tanımlanan çift yönlü bir M:1 ilişki salt-okunur bir ilişki halini alacak, böylece ilişkinin
yönetimi 1:M tarafında olacaktır.
1:M ilişkileri inceleyeceğimiz bir sonraki yazımızda görüşmek üzere…