11 Eylül 2020 Cuma

JPA @SequenceGenerator Anotasyonu - Kendi Sequence Tanımımızı Yapmak İçindir

Giriş
Bu anotasyon üye alan üzerinde veya sınıf üzerinde tanımlanabilir. Sınıf üzerinde tanımlamak için şöyle yaparız
@SequenceGenerator(sequenceName = "MY_DB_SEQUENCE", name = "sequence")
public class MyClass {
  ...
}
PostgreSQL
PostgreSQL için açıklama şöyle. Yani Java kodunda kullanılan allocationSize alanı ile veri tabanındaki increment değeri aynı olmalı.
AllocationSize and Sequence Increment Size
One thing to note here is that the allocationSize property in Hibernate needs to be the same as the increment size for the underlying sequence in Postgres.

This is so that Hibernate and the underlying sequence don’t go “out of sync” in terms of the ids that they’re holding. This also prevents any issues with a distributed architecture where multiple servers are writing to the same table.

By default, the increment size for our Postgres sequences was 1. We wrote a very quick migration to change it to match our allocationSize:

ALTER SEQUENCE entity_id_seq INCREMENT 50;

Now, Hibernate will only need to make 1 call to get the list of ids per 50 inserts.

And it’ll only need 1 call to insert those 50 rows as well.

Here’s a summary of what we learned from this issue:

  • With Hibernate, start using database sequence-based identity value generation as soon as possible — especially if you foresee the number of writes increasing.

  • Keep the allocationSize and the underlying Postgres sequence increment size params the same to avoid id collisions and support a distributed system.
allocationSize Alanı
Sequence'tan her select işleminde kaç tane sayı çekeceğimizi belirtir.
Örnek
Şöyle yaparız.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "school_generator")
@SequenceGenerator(name="school_generator", sequenceName = "school_seq",
 allocationSize=1)
@Column(name = "school_id")
private Long id;
initialValue Alanı - Veri tabanını Kendimiz Yaratırken Kullanılır
Örnek - Oracle
Önce veritabanında sequence yaratılır. Oracle Sequence her sorgulandığında yeni bir sayı verir.
create sequence sub_seq
       MINVALUE 1 
       MAXVALUE 999999999999999999999999999 
       START WITH 1
       INCREMENT BY 1 
       CACHE 100 
       NOCYCLE ;
Sınıfı kodlamak için şöyle yaparız.
@Id
@SequenceGenerator(name="sub_seq", initialValue=1, allocationSize=1,
sequenceName="sub_seq")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sub_seq")  
private Integer pid;
Burada SequenceGenerator aslında javax.persistence.SequenceGenerator. Hibernate bu sınıfı Hilo algoritmasını kullanarak gerçekleştiriyor. Bu da sayılarda boşluklara sebep oluyor. Boşluklardan kaçınmak için initialValue = 1, ve allocationSize = 1 vermek gerekiyor.

Eğer sequence mevcut değilse şöyle bir hata alırız.
ERROR: could not read a hi value - you need to populate the table: hibernate_sequence
name Alanı
@GeneratedValue anotasyonundaki generator alanı ile aynı olmalıdır.
Örnek
Şöyle yaparız.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator",  sequenceName = "product_id_seq")
private Long id;
sequenceName Alanı
Veritabanındaki sequence ismidir.

Hiç yorum yok:

Yorum Gönder