JPA Nedir?

Java Persistence API (JPA), Object Relational Mapping (ORM) teknoloji apilerinden bir tanesi olup database tarafinda tum table larin program tarafinda ki bir (entity) class a denk gelmesi ve tum islemlerinin bu (entity) class uzerinde yapilmasini sağlayan bir teknolojidir.
Amaç tabi ki sadece bu değil. JPA teknolojisi ile, veritabanı ile bilgi alışverişi esnasında veri güvenliği ve performans da üst düzeye çıkarılmış olur.

Entity
JPA’yı kullanarak veri tabanında kalıcı kılınacak olan nesneye entity denir. Bir nesnenin entity olması için gerek ve yeter şart o nesnenin kendisinden üretileceği sınıfın ya @Entity notuyla notlandırılması ya da XML ayarlarında entity olarak ifade edilmesidir. (Biz bu yazıda genel olarak notlu ayarı temel alacağımızdan okuyucu, aksi söylenmedikçe bütün ayarların notlarla ifade edildiğini varsaymalıdır.) Entity bir iç sınıf (inner class), bir interface ya da enum tipi veya final olmamalıdır ve public ya da protected olan bir argumansız yapılandırıcısı (no-arg constructor) olmalıdır.

Entitynin veri tabanında saklanancak olan kalıcı durumu (persistent state), tamamen nesne değişkenlerinden oluşacaktır. Bu yüzden kalıcı durumun parçası olacak nesne değişkenleri final olmamalıdır. Nesne değişkenleri private olabilir hatta olmalıdır ve kalıcı olan nesnenin istemcileri (client), nesnenin değişkenlerine get/set metotları ile ulaşmalıdır. Entitylerin kalıcılığının minimum sayıda alandan (nesne değişkeni) oluşması gerektiği düşünüldüğünde, veri tabanında kalıcı olması gerekmeyen değişkenler @Transient ile notlandırılması gerekir.

Bir sınıfın entity olması için teorik olarak zorunlu olmamakla birlikte konulmadığında pratikte pek çok sıkıntı çıkardığı için gerekli olarak belirttiğimiz bir diğer not ise @Id’dir. Bu not, notlandırdığı alanın, içinde bulunduğu nesnenin kimlik (identity) bilgisini ifade etmesini ve veri tabanında da bir anahtar alana (primary key) karşı gelmesini sağlamaktadır.

JPA, bir JPA ürünü ve kullanılacak veri tabanıyla ilgili olarak yapılacak ayarları classpathde META-INF klasörünün altında persistence.xml isimli bir dosyada olmasını bekler.
persistence.xml dosyasındaki her kalıcılık birimi için bir JPA sağlayıcı (provider) belirtilmelidir.

jpa1

Bir entity sınıfındaki eşleştireceğiniz ilk alan daima o sınıftan oluşturulan nesnelerin ayırt edici özelliği olan ve @Id ile notlandırılan kimlik (identity) alanı olmalıdır. Bazen kimlik bilgisinin, veri tabanı gibi bir yapı tarafından ardışıl olarak üretilmesini isteriz. Bu durumda @GeneratedValue notu ile bu not içinde @GenerationType notunu kullanıp, JPA sağlayıcının ve veri tabanının özelliklerine göre mümkün olan kimlik bilgisi üretme stratejilerinden en uygun olanını seçebiliriz. @GeneratedValue notu isteğe bağlı iki özellik alır: String tipinde bir üretici ile GenerationType enum tipinde bir üretim tipi. GenerationType’ın, AUTO, IDENTITY, SEQUENCE ve TABLE olmak üzere 4 nesnesi vardır. Örneğin Customer2 sınıfının custId alanını, üretim şeklini Hibernate’e bırakarak aşağıdaki gibi notlandırabiliriz:
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = “CUSTOMERID”) private long custId;
Hibernate bu durumda Oracle XE’de HIBERNATE_SEQUENCE isimli bir dizi (sequence) oluşturup Customer2 sınıfının kimlik bilgisini buradan üretmektedir. Bu durumda Test sınıfımızda artık Customer2 nesnelerini oluştururken kimlik bilgisi geçmemeliyiz, aksi taktirde hata alırız.

EntityManager

Özellikle geliştirme ve test amaçlı olarak hızlıca yazılan uygulamalarda JPA’in veri tabanında şema (schema) oluşturma yeteneğinden faydalanılır. Böyle bir ayar durumunda, EntityManager isimli nesne ilk oluşturulduğunda, JPA tamamen varsayılan ayarları kullanarak veri tabanında @Entity olarak notlandırılan sınıfların isimlerini kullanarak aynı isimde tablolar oluşturur ve tabloların sütunlarını da entity sınıflarının kalıcı olan alanlarının isimleriyle aynı yapar ve ve bu sütunlara uygun tipler atar.

persistence.xml ‘deki ; ayar satırı ile de,
hibernate.hbm2ddl.auto: Bu özelliklik Hibernate’e veri tabanındaki şemayla alakalı nasıl bir tavır takınacağını öğretmek içindir. Yukarıdaki dosyada bu ayar “create” olduğu için Hibernate ilk EntityManager nesnesi oluşturulduğunda veri tabanına gidip varsayılan değerlerle bir şema oluşturacaktır. Şemanızı ilk defa oluşturduktan sonra bu özelliğin değerini “update”e değiştirebilirsiniz.

EntityManager, veri tabanına açılan bir oturumdur (session), yapı itibariyla Java’nın web katmanındaki HttpSession nesnesine benzer ya da Hibernate’in orijinal API’sinin Session nesnesiyle tamamen aynı işi yapar. Dolayısıyla EntityManager’i olabildiğince kısa aralıklar içinde kullanmak, yani bu nesnenin ömrünü olabildiğince kısa tutmak gereklidir

Zaten EntityManager nesnesini kullanmanın iki yolu olabilir: Ya nesne değişkeni ya da metot değişkeni (local) olarak. Nesne değişkeni olarak kullandığınızda bu nesnenin pek çok metotta aynı anda kullanılması söz konusudur. Buradaki problem EntityManager’in thread-safe olmamasıdır. EntityManagerFactory thread-safedir, dolayısıyla bu nesneyi, nesne değişkeni olarak kullanıp, entitylerle alakalı YODS işlemlerini yapacağımız metotlarda, bu nesne üzerinden yerel bir EntityManager nesnesi almak daha doğru bir yaklaşım olacaktır. Bu durumda EntityTransaction nesnesini de kullanarak EntityManager nesnesi üzerindeki metotları çağırıp, sonra da close ile EntityManager nesnesini kapatarak programımızı yazarız.

Aşağıda bu sınıfın üzerinde çağırabileceğimiz nesne hayat döngüsünü düzenleyen metotlar ve kullanımları sıralanmıştır:

* void persist(Object entity) Yeni bir entityyi veri tabanında kalıcı kılar ve nesneyi yönetilir (managed) hale getirilir.
* Object find(Class entityClass, Object id) Geçilen entityClass’ın geçilen id’ye sahip nesnesini veri tabanından getirir.
* Object merge(Object entity) Koparılmış (detached) haldeki nesneye yapılan değişiklikleri, veri tabanındaki entityle birleştirir. Bu metot geriye birleştirilmiş entityi döndürür.
* void remove(Object entity) Entityyi veri tabanından siler.
* void refresh(Object entity) Entitynin veri tabanındaki halini getirip kalıcılık bağlamındakinin üzerine yazar.
* boolean contains(Object entity) Geçilen nesnenin kalıcılık ortamında entity olarak olup olmadığını boolean olarak geri döndürür.
* void clear() Kalıcılık ortamını temizler ve ortamda bulunan nesneleri koparılmış (detached) hale getirir.
* void flush() Kalıcılık ortamınındaki entitylere yapılan değişiklikleri veri tabanına gönderir (synchronize).

EntityManager tarafından persist ile kalıcı kılınan ya da find ile veri tabanından getirilen entitylerin durumu (state) yine EntityManager tarafından takip edilir. Böyle bir entityye “yönetilen” (managed) denir. Yönetilen nesnelere yapılan değişiklikler veri tabanına EntityManager tarafından yansıtıldığı için ayrıca güncelleme gibi bir metot çağırmaya gerek yoktur.

İşlem (Transaction) Yönetimi
Yukarıda EntityManager’in metotlarını incelemeden de anlaşılacağı gibi entityler işlem içerisinde kalıcı hale getirilirler (persist), güncellenirler (merge) ve silinirler (remove). Ayrıca yönetilen entitylere yapılan güncellemeler, EntityManager nesnesi tarafından takip edilir ve ne zaman bu nesne üzerinden ulaşılan EntityTransaction nesnesi begin ile başlatılıp commit ile bitirilirse yukarıdaki üç metotun sonucu ve kalıcılık bağlamındaki tüm güncellemeler veri tabanına yansıtılır.
EnetityManager nesnesi üzerindeki metotları çağırırken ya da başka bir sebeple ortaya çıkan durumlardan dolayı entityler üzerindeki değişiklikleri EntityTransaction üzerinde commit’i çağırarak veri tabanına göndermek yerine rollback’i çağırarak ile geri almak isteyebilirsiniz. rollback en son begin’den sonraki entitylere yapılan değişiklikleri geli alır, veri tabanına yansıtmaz.

Entity Hayat Döngüsü (Life Cycle)

Bir entity şu dört durumdan birinde olabilir: yeni (new), yönetilen (managed), silinmiş (removed) ve koparılmış (detached). (Bkz. lifeCycle())
Bir entity ilk yaratıldığında yeni (new) durumundadır. Bu durumda olan entitynin veri tabanıyla bir ilgisi yoktur, yani henüz veri tabanına yazılmamıştır. EntityManager’in persist metotuyla veri tabanında kalıcı hale gelir ve durumu yönetilen (managed) olur. (Bkz. createACustomer()) Yönetilen entity var olan kalıcılık ortamında bulunur ve durumu EntityManager tarafından takip edilir. Bu nesneye yapılan değişiklikler EntityTransaction nesnesine yapılan ilk commit çağrısında veri tabanına yansılıtır ve nesne yönetilen olarak kalmaya devam eder. (Bkz. createAndManageCustomer())

Veri tabanındaki bir entity EntityManager‘in find metotu ya da daha ileride göreceğimiz Query nesneleriyle veri tabanında getirildiğinde yine yönetilen durumuna girer. Bu durumdayken EntityManager’in remove metotuyla silinmiş hale gelir. Tekrardan veri tabanına yazılması için persist metotuna geçilmesi gereklidir. (Bkz. removeACustomer())

EntityManager üzerinde çağırılacak close ya da clear metotlarıyla da kalıcılık bağlamındaki bütün nesneler koparılmış hale gelirler ve durumlarındaki değişiklikler artık EntityManager tarafından takip edilmezler. Bu tür entitylerin durumlarını veri tabanında güncellemek ve tekrar yönetilen hale döndürmek için merge metotunu kullanırız. merge metotu, uzun işlem (long transaction) denen ve entitynin genelde içinde bulunduğu katmandan başka katmanlara gidip, orada değiştirildikten sonra değişikliklerin veri tabanına yansıtılması için geri gönderildiğinde kullanılır. Örneğin veri tabanında getirdiğiniz entity bir JSP sayfasında kullanıcıya görüntülenecek ve kullanıcının bazı alanları değiştirip kaydetmesine izin verilecekse, bunu yapmanın iki yolu olabilir: Ya EntityManager nesnesini JSP içinde alıp üzerindeki metotları kullanarak entitynizi değiştireceksiniz ki bu JSP içinde veri katmanıyla ilgili iş yapmak anlamına gelecektir ve popüler olan MVC (Model-View-Controller) tasarım desenine (design pattern) aykırı bir durum oluşturacaktır. Ya da entitynizi veri tabanında değiştirecek EntityManager nesnesini arka tarafta yani veri katmanında tutacaksınız ve entitynizi JSP sayfasına değiştirilmek üzere göndereceksiniz ve bunu yaptığınız yerde de EntityManager nesnesi üzerinde close metotunu çağıracaksınız. Bu durumda entityniz koparılmış olacaktır. Dolayısıyla JSP’de değiştirilen entity, veri katmanına tekrar gönderildiğinde, yeni bir EntityManager nesnesi oluşturup bir işlem içerisinde bu kez merge metotunu çağırarak güncelleyeceksiniz. Bu ikinci yöntem çok daha sağlıklı olup uzun işlem olarak adlandırılır. (Bkz. detachACustomer())”

Kaynaklar…
http://www.javaturk.org/?p=1119-
-http://kodcu.com/2011/10/java-persistence-giris/-
-http://www.turkishh.com/programlama/java-persistence-api-jpa-ile-programlama-1/-
-http://www.serefakyuz.com/2011/07/jpa-nedir.html-
-http://www.aliboyraz.com/jpa-nedir-1/-

Reklamlar

2 Yanıt to “JPA Nedir?”

  1. fatihdurmus Says:

    Belirttiğiniz şekilde düzeltme yapılmıştır.
    Tamamı alıntıdır anlayamadığım ufak bir iki nokta yada bazı yerlerin açıklaması daha iyi olan bir iki destek kelime diğer sitelerden alınmıştır.

  2. fatihdurmus Says:

    Çok güzel anlatmışsınız, yrıca teşşekkürederim.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s


%d blogcu bunu beğendi: