JPA (Java Persistence API)-09
Önceki yazımda Element Collection anotasyonlarından bahsetmiştim. Bu yazımda ise entity’lerin ilişkilerinden bahsedeceğim.
One To One
- İki entity düşünelim, biri user biri adres olsun. Bu entity’ lerin kendilerine ait primary key’ leri var yani veri tabanında Customer ve Adres adında iki tablo oluşacak. Bu ilişki bir tablodan diğerine foreign key olarak yüklenecek.
- One to One ilişkisi ise her bir müşterinin yalnızca bir adresi olacak ve her adres yalnızca bir müşteriye ait olacak şeklinde kısaca tanımlanabilir.
3. Maven projemizi oluşturup customer sınıfımızı tanımladık. İşte sınıfın içeriği :
- Customer sınıfı içinde Address sınıfının bir nesnesini tanımlayarak iki sınıf arasındaki ilişkiyi one to one şeklinde ayarlıyoruz.
- İşte Address sınıfının içeriği :
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int addressId;
private String street;
private String city;
private int postalCode;
// ....
// Set-Get Metodları
// ....- addressId ise Customer tablosuna referans verilen foreign key’ dir.
- Şimdi de Test sınıfına bakalım :
- Hem Address hem Customer sınıfı birer entity olduğu için ikisini de Test sınıfında persist etmemiz gerekiyor.
- Kodu çalıştırdığımızda ise veri tabanına bir göz atalım :
- Customer tablosu :
- Address tablosu :
4. Customer entity’ si içinde Addres nesnesini tanımlıyoruz. Ancak tanımlarken list veya dizi kullanmıyoruz çünkü her bir adres yalnızca bir müşteriye ait her bir müşterinin ise sadece bir adresi var.
One To One — Mapped By
5. Mapped By anotasyonu birebir ilişkinin ters tarafını belirtmek için kullanılır.
6. Mapped By’ ın kullanıldığı yer ilişkinin sahibinin olduğu entity değildir. Yavru sınıftan ana sınıfa ulaşmak için kullanılır.
Get Fatma Aleyna Doğan’s stories in your inbox
Join Medium for free to get updates from this writer.
7. Address ve Customer entity’ lerini burada da kullanmaya devam edeceğiz. Ufak değişikliklerle işte Customer sınıfının içeriği :
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int customerId;
private String firstName;
private String lastName;
private Date birthOfDate;
@OneToOne
@JoinColumn(name="address_Id")
private Address address;- Address sınıfı :
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int addressId;
private String street;
private String city;
private int postalCode;
// @OneToOne
// @JoinColumn(name="address_Id")
// private Address address;
@OneToOne(mappedBy = "address")
private Customer customer;- Bu şekilde ilişkinin sahibinin Customer sınıfı olduğunu belirttik. Böylece Address tablosunda customer_ıd kolonu çıkmayacak ve Address sınıfı üzerinden Customer tablosuna erişebileceğiz.
- TestPersist sınıfının içeriği :
- Kodu çalıştırdıktan sonra veri tabanındaki Customer tablosuna bir göz atalım :
- Address tablosu :
8. Şimdi de find metoduyla veri çağırma işlemi yapalım. Ama öncelikle persistence.xml’ de tablo oluşturma kısmını create’ ten update’ e çevirelim.
- İşte TestFind sınıfının içeriği :
package com.proje.test;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.proje.model.Address;
import com.proje.model.Customer;
public class TestFind {
public static void main(String[] args) {
EntityManagerFactory factory=Persistence.createEntityManagerFactory("persistence-unit");
EntityManager entityManager=factory.createEntityManager();
Address address=entityManager.find(Address.class, 2);
System.out.println(address); // address tablosu üzerinden mappedBy anotasyonula customer tablosuna eriştik.
}
}- Kodun çıktısı ise :
One To One — Cascade Type
9. Cascade Type bir entity’ nin diğer entity üzerindeki işlevleri/özellikleri/yetkileridir.
10. Normalde TestPersit sınıfında hem Customer entity’sini hem de Address entity’ sini persist ediyorduk. Ancak Customer’ e persist özelliği verirsek -Address üzerindeki yetkisini tanımlarsak — artık TestPersist’ te Address’ i persist etmemize gerek kalmıyor. Sadece Customer’ ı persist ettiğimizde Address de persist olmuş oluyor. (veri tabanına kaydı gerçekleşmiş oluyor)
- Customer sınıfının içeriği :
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int customerId;
private String firstName;
private String lastName;
private Date birthOfDate;
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="address_Id")
private Address address;- Address sınıfımızın içeriği ise yukardaki örnekle aynı.
CascadeType.REMOVE = Fatma Doğan adlı müşteriye ait olan kayıt Customer tablosundan silindiğinde bu kayıtla ilgili ilişkili adreslerin de silinmesini sağlar. (silme işlemini transaction komutları arasında gerçekleştiriyoruz)
CascadeType.MERGE = Sahip olan tablonun herhangi bir özelliği güncellendiğinde ilişkili olduğu tabloların da güncellenmesini sağlar. (güncelleme işlemini transaction komutları arasında gerçekleştiriyoruz)
CascadeType.ALL = tüm bu şartlara izin verir.
- Ayrıca tüm şartlara değil de sadece belirli birkaç özelliğe izin vermek istediğimizde ise şu şekilde kullanırız :
@OneToOne(cascade = {CascadeType.REMOVE,CascadeType.PERSIST})Böylece yazımın sonuna geldim vakit ayırdığınız için teşekkürler.










