ArÅŸiv

Buna etikete sahip yazılar; ‘Hibernate’

Hibernate dynamic-insert, dynamic-update

Cumartesi, 06 Ağu 2011 Yorum yapılmamış

Hibernate’in bir kullanılabilir özelliÄŸi daha; dynamic-insert, dynamic-update : )

dynamic-update : Güncelleme sql ifadesini(update sql) çalışma zamanında sadece değişen kolonlara göre dinamik olarak oluşturur.
dynamic-insert : Kayıt ekleme sql ifadesini(insert sql) çalışma zamanında sadece veri girilmiş kolonlara göre dinamik olarak oluşturur.

Şöyle ki;

@Entity
@Table(name = "PERSONEL")
@org.hibernate.annotations.Entity(dynamicInsert=true,dynamicUpdate=true)
public class PERSONEL{
...
...
...
}

Sadece AD, SOYAD ve TC_KIMLIK_NO alanlarının girildiği bir kayıt işlemi sonrası

INSERT INTO PERSONEL(AD, SOYAD, PERSONEL_NO, TC_KIMLIK_NO, YAS, CINSIYET, DOGUM_TARIHI)  VALUES (?, ?, ?, ?, ?, ?, ?)

gibi bir sql ifadesi oluşması yerine

INSERT INTO PERSONEL(AD, SOYAD, TC_KIMLIK_NO)  VALUES (?, ?, ?)

gibi sadece veri girilmiş alanların dahil edildiği bir sql ifadesi oluşuyor.

Performans açısından ise şöyle bir ters orantı var. Normal koşullarda Hibernate her varlık sınıfı için üretilen ekleme , güncelleme, sorgulama sql ifadelerini belleğine alır. Böylece her ekleme, güncelleme, sorgulama işlemi için bir sql ifadesi oluşturması gerekmez. Bu performans açısından bir artı getirir. Amma lakin ki bu özellik aktif hale getirildiğinde de her ekleme, güncelleme işlemi için bir sql ifadesi oluşturma işi çıkıyor ortaya. Dolayısıyla çok fazla kolon içeren tablolar için çalıştırılacak sql ifadesini minumuma indirerek performans açısından bir artı getirebilse de diğer durumlar için karar vermek gerekiyor, bu özelliği aktif yapıp yapmamaya.

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail

Hibernate @SqlDelete

Cumartesi, 06 Ağu 2011 Yorum yapılmamış

Hibernate’in yeni keÅŸfettiÄŸim bir özelliÄŸi varlık sınıflarına uygulanabilen @SqlDelete, @SqlUpdate, @SqlInsert bildirimleri. Bu sayede ilgili varlık sınıflarını kaydetme, güncelleme ve silme iÅŸlemleri sırasında hangi sql ifadesinin çalışacağını belirleyebiliyoruz. Bir nevi EntityManager sınıfının persist, merge ve remove metotları sonucu oluÅŸacak olan ekleme, güncelleme ve silme sql ifadelerini ezmiÅŸ oluyoruz. Özellikle silme iÅŸlemi için oldukça faydalı olabilir diye düşündüm.

Mesela; Hesap nesnelerini karşılayan Hesap sınıfları için ne zaman entityManager.remove(herhangiBirHesap) desek, bu nesneyi fiziksel olarak silmek yerine mantıksal olarak durumunu pasif yapmak isteyebiliriz. “Soft delete” olarak bilinen durum yani. Bu gibi durumlar için proje genelinde bir kod tasarrufu ve temizliÄŸi saÄŸlanabilir gibi.

Ayrıca sınıf tanımında kullanılacak @Where bildirimi ile de veritabanından Hesap tablosuna sorgu atan sql ifadelerine bir koşul konulabiliyor. Böylece de durumunu pasif yaptığımız nesneler sorgu sonuçlarında gelmiyor. Bu yazılan sql ifadeleri için hql kullanılamıyor bu arada, sql yazmak gerekiyor.

Şöyle ki;

@Entity
@Table(name = “HESAP”)
@SQLDelete(sql=”update HESAP set DURUM=0 WHERE ID=?”)
@Where(clause=”DURUM <>0″)
public class Hesap {



}

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail

Object references an unsaved transient instance

Cuma, 07 May 2010 Yorum yapılmamış

Hibernate API ‘yi kullananlar TransientObjectException:Object references an unsaved transient instance – save the transient instance before flushing hatası iÅŸle karşılaÅŸmışlardır mutlaka. Şöyle bir örnek üzerinden açıklayacak olursak; Araba ve Kullanici adli iki modelimiz olduÄŸunu ve Araba modelinde

@ManyToOne()
@JoinColumn(name = “KULLANICI_ID”)
private Kullanici kullanici;

şeklinde bir Kullanici alanımız olduğunu varsayalım. Aksiyon sınıfında;


araba.setKullanici(kullanici);
entityManager.persist(araba);
entityManager.flush();

ÅŸeklinde bir kod bloÄŸu yukarıdaki hatayı almamıza sebep olacaktır. Kullanici nesnesi sessionda varolmasına raÄŸmen henüz veritabaninda mevcut deÄŸildir, yani “transient object” tanımına girmektedir. Araba tablosunda “foreign key” olarak bulunan KULLANICI_ID alanına yerleÅŸtirilecek bir ID yoktur ortalıklarda. Dolayısıyla iliÅŸki kurulamaz. Hatayı iki ÅŸekilde gidermek mümkün. Birincisi kod bloÄŸunu;


araba.setKullanici(kullanici);
entityManager.persist(araba.getKullanici());
entityManager.flush();

entityManager.persist(araba);
entityManager.flush();

şeklinde düzenleyip önce Kullanici nesnesini veritabanına yazmak, ikincisi de ilişkiyi

@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = “KULLANICI_ID”)
private Kullanici kullanici;

şeklinde tanımlayarak bu Araba veritabanına kaydedilirken ve güncellenirken Kullanici nesnesinin de veritabanina yazilmasini sağlamak. Elbette ki sağlıklı olan annotation da ilişkinin özelliğini bildirerek bu gibi kontrolleri ve performansı API nin kendisine bırakmak.

Benzer bir durum OneToMany() ilişkilerde de sözkonusu. Çözüm yine benzer şekilde.

FacebooktwitterlinkedinmailFacebooktwitterlinkedinmail