9 Temmuz 2018 Pazartesi

JPA @GeneratedValue Anotasyonu

Giriş
Şu satırları dahil ederiz.
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
Açıklaması şöyle.
The @GeneratedValue annotation denotes that a value for a column, which must be annotated with @Id is generated. The elements strategy and generator on the annotation describe how the generated value is obtained.
Alan Vermemek
Bazı kodlarda şöyle. Sanırım kendi sayacımızı kullanırsak böyle yapıyoruz.
@Entity
public class Cheese {

  @Id
  @GeneratedValue
  private int id;
  ...
}
generator Alanı
generator kendi kodumuzla bir değer üreteceksek kullanılır.

Örnek
Şöyle yaparız. @GenericGenerator Hibernate anotasyonu
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "uuid2")
@Column(name = "id",nullable = false, updatable=false)
@Type(type="uuid-char")
private UUID id;
Örnek
Şöyle yaparız.
public class StringIdGenerator implements IdentifierGenerator {

  public Serializable generate(SessionImplementor session, Object object)
  throws HibernateException {
    ...
  }
}

@Entity
@GenericGenerator(name = "pt_sequence", strategy = "dao.StringIdGenerator")
public class P {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY,generator = "pt_sequence")
  String id; 
  ...
} 
strategy Alanı
Eğer veritabanı bir değer üretecekse kullanılır.

1. AUTO Seçeneği
Açıklaması şöyle.
The AUTO generation strategy is the default, and this setting simply chooses the primary key generation strategy that is the default for the database in question, which quite typically is IDENTITY, although it might be TABLE or SEQUENCE depending upon how the database is configured. The AUTO strategy is typically recommended, as it makes your code and your applications most portable.
Şöyle yaparız.
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "room_id")
private Integer id;
PostgreSQL ile çalışırken eğer sütun Serial değilse bile Hibernate hibernate_sequence nesnesini kullanarak değer üretebiliyor.

2. IDENTITY Seçeneği
Açıklaması şöyle.
The IDENTITY option simply allows the database to generate a unique primary key for your application. No sequence or table is used to maintain the primary key information, but instead, the database will just pick an appropriate, unique number for Hibernate to assign to the primary key of the entity. With MySQL, the first lowest numbered primary key available in the table in question is chosen, although this behavior may differ from database to database.
Örnek
MySql'de identity şöyle kullanılır. id sütununun auto_increment olarak yaratılması gerekir.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Long id;
Örnek
PosgreSQL'de sütunun "Serial" olarak yaratılması gerekir. Şöyle yaparız.
CREATE TABLE employee
(
  id serial NOT NULL,
  firstname character varying(20),
  lastname character varying(20),
  birth_date date,
  cell_phone character varying(15),
  CONSTRAINT employee_pkey PRIMARY KEY (id )
)

3. SEQUENCE Seçeneği
Açıklaması şöyle.
Some database vendors support the use of a database sequence object for maintaining primary keys. To use a sequence, you set the GenerationType strategy to SEQUENCE, specify the name of the generator annotation, and then provide the @SequenceGenerator annotation that has attributes for defining both the name of the sequence annotation, and the name of the actual sequence object in the database.
Eğer kendi sequence tanımımızı yapmazsak Hibernate ismi hibernate_sequence olan bir taneyi kullanmaya çalışır. Eğer bu sequence yoksa şu exceptino fırlatılır
org.hibernate.HibernateException: Missing sequence or table: hibernate_sequence
Örnek
PostgreSQL'de şöyle yaparız. Bu durumda Hibernate ismi hibernate_sequence nesnesinden sayıları sıra ile çeker.
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)  
private Integer pid;
Örnek
Oracle'da şöyle kullanılır. Ö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
4. Table Seçeneği
Açıklaması şöyle.
The GenerationType.TABLE gets only rarely used nowadays. It simulates a sequence by storing and updating its current value in a database table which requires the use of pessimistic locks which put all transactions into a sequential order. This slows down your application, and you should, therefore, prefer the GenerationType.SEQUENCE, if your database supports sequences, which most popular databases do.



Hiç yorum yok:

Yorum Gönder