JPA

JPA-02-ID Generation 1-Identity Ve Sequence

Merhaba arkadaşlar. Uzunca bir süredir devam etmek istediğim ama edemediğim JPA yazılarıma bu yazı ile devam edeceğim inşaAllah. Hem benim hem sizin için oldukça olacağını düşündüğüm yazılara seri şekilde devam edebilirim inşaAllah.

Bu dersimizde konumuz Id Generation olacak. Türkçesi ile Id Üretme diyebiliriz bu konuya. Id üretme dediğimizde anlamamız gereken id atamasını nasıl otomatize edebileceğimizdir. JPA çatısını geliştirenler id üretmeyi 3 şekilde yapabilmeyi sağlamışlar. Bunlar:

  • Identity
  • Sequence
  • TableGenerator.

Bu çeşitliliğin sebebi de aslında veri tabanı geliştiren şirketlerin id otomatize mekanizmasında yaşanan farklılıklardır arkadaşlar. Örnek vermek gerekirse bugün en sağlam ilişkisel veri tabanı olarak görülen Oracle ve ona rakip olabilecek belki de tek veri tabanı olan açık kaynak kodlu Postgre SQL veri tabanı id otomatizesini Sequence ile yapıyorlar.  Microsoft’un SQL Server’ı ile MySql ise Identity ile işlemi yapıyor.

Söz konusu çatımız JPA olduğu ve kodumuz da Java kodu olacağı için Entity sınıfları içinde hangi veri türlerinin id olabileceğini de öğrenmek gerekir. Id olabilecek veri türü listesi şöyle:

  • Byte
  • Integer
  • Short
  • Long
  • Character
  • String
  • BigInteger
  • Date (Hem util.Date Hem sql.Date)

Identity İle Otomatize Etme

Id otomatizesi içinde belki de en kolayı bu arkadaşlar.  Identity ile otomatize işleminde işlem veri tabanı tarafından yapılıyor. Örneğin MySql kullanırken bir sütuna Auto Increment özelliği veririz ve bu genelde Primary Key için olur. Her kayıt attığımızda bu sütun kendi değerini otomatik arttırır. JPA’ya da bunu Idendity olarak tanıttığımızda işlem tamamen veri tabanına bırakılmış olur. Peki bunu nasıl kullanıyoruz? Örnek kod şöyle:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String name;
    public String getName() 
    {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    } 
}

Kod içinde göreceğiniz üzere Id’mizin üretmesinin nasıl olacağına karar verirken @GeneratedValue notasyonunu kullanıyoruz.  Bu notasyonun bir özelliği olan strategy ile de üretmenin türünü atıyoruz.Üretme türleri GenerationType sınıfının içinde yer alıyor ve biz de seçimimizi bu sınıftan yapıyoruz. Bu nedenle strategy=GenerationType.IDENTITY ifadesini kullanıyoruz.

Id üretmesini bu şekilde kullandığımızda performan düşüşü olacağına dair eleştiriler yöneltilmektedir arkadaşalar fakat diğer yandan kullanımı da çok kolay olduğu için tercih edilebilir. Bunun yanında bir artısı da şu arkadaşlar. Olaya JPA değilde veri tabanı karıştığından id bilgisi hafızaya alınmıyor ve bu nedenle de hafızadan tasarruf sağlanabiliyor.

Sequence İle Otomatize Etme

Identity yönteminden farklı olarak Sequence ile id otomatizesinde olaya biz müdahele ediyoruz. Bu konuyu örnek kodumuz üzerinden inceleyelim arkadaşlar.

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;

@Entity
@SequenceGenerator(name = Car.CAR_SEQUENCE_NAME, sequenceName = Car.CAR_SEQUENCE_NAME, initialValue =10,
allocationSize =53)
public class Car {
public static final String CAR_SEQUENCE_NAME = "CAR_SEQUENCE_ID";
        
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = CAR_SEQUENCE_NAME)
private int id;

    private String name;
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
}

Id üretmesini Sequence ile yapmak istersek @SequenceGenerator notasyonunu kullanmamız gerekir arkadaşlar.  Kodu incelediğimizde bu notasyonun 4 özelliğini kullandığımızı görüyor. Bu notasyonun özelliklerine sırası ile bakalım:

  • name özelliği uygulama içinde Sequence’in adını tanımlamaya yarar.
  • sequenceName özelliği verilen string’i veri tabanı katmanında sequence adı olarak tanıtır.
  • initialValue özelliği id sütununun kaçtan başlıyacağını bildirir. Bu örnekte gelecek ilk kayıt 10 numaralı id’ye sahip olacak.
  • allocationSize özelliği cache yapısı içinde kaç tane bilgi id tutulacak onu belirtmeye yarar. Bu örnekte girilecek ilk kaydın id’si 10 olacak ve uygulama biz allocationSize’ı 53 verdiğimiz için 10 ile 63 arasındaki id’leri tutacak.

@SequenceGenerator notasyonu ile tanımlama yaptıktan sonra yine @GeneratedValue notasyonunun strategy özelliğine GenerationType sınıfındaki SEQUENCE‘i atıyoruz. Akabinde Sequence kullandığımız için bir de generator tanımlaması yapmamız gerekiyor. Buna da

Bu yazıyı yazarken bir taraftan yazdığım kodları denemeye de çalışıyorum ve bu kod MySql altında çalışmadı arkadaşlar. StackOverflow’da konuyu kesinliğe kavuşturmak için araştırma da yaptım ve bir çok yerde MySql’in Sequence’i desteklemediğini gördüm. Yani yukarıda da bahsettiğim üzere MySql Identity destekliyor.

Bu yazıda da bu kadar arkadaşlar. Gelecek yazıda id üretmenin diğer iki konusu olan TableGenerator ve Auto’yu işleyeceğiz. Sağlıcakla kalın.

4 Yorum

  • İlkay Bey, Id Genelleştirme yerine Id üretme, oluşturma demek daha doğru olmaz mı?
    Gördüğüm kadarıyla da ‘Generation’ kelimesinin öyle bir anlamı da yok.
    Lütfen dikkate alın.
    İyi çalışmalar.

    • Merhaba.
      Öncelikle teşekkür ederim. Yazı içinde gerekli yerlerde düzenlemeleri yaptım. Genaration kelemesini yazıyı yazdığım sırada General kelimesi ile karıştırmışım.
      İkinci olarak da şunu sormak istiyorum. Benim yazıya gelen yorumu dikkate almayan, hatalarımda ısrar eden bir insan olduğumu mu düşünüyorsunuz ki “Lütfen dikkate alın.” şeklinde bir ifadeniz oldu?
      Size de iyi çalışmalar.

      • Hayır, ilk defa yorum yazdım yazılarınıza.
        Asıl amaç lütfen kelimesini kullanmaktı.
        İyi çalışmalar.

İlkay Günel için bir yanıt yazın X