You are on page 1of 25

o m

i.c
dil
Hacettepe Üniversitesi

Bilgisayar Mühendisliği
Bölümü
va

EJB 3.0
ja
w.

Yeliz Özdil
20122378
ww
İÇİNDEKİLER

Günümüz EJB Modeli

m
Neden EJB 3.0?
Java 5’te Tanımlanan Özel Açıklamalar
Durumsuz Oturum Çekirdeği

o
EJB 2.1
Üreteç Arayüzü
Uzak Arayüz

i.c
Çekirdek Sınıfı
Yaygınlaştırma Belirtim Belgesi
İstemci Test Sınıfı
EJB 3.0
Çekirdek Sınıfı
Çekirdek Arayüzü
İstemci Test Sınıfı
dil
Kap Tabanlı Kalıcılık ile Varlık Çekirdeği
va
EJB 2.1
Yerel Üreteç Arayüzü
Yerel Arayüz
Çekirdek Sınıfı
ja

Yaygınlaştırma Belirtim Belgesi


EJB 3.0
Çekirdek Sınıfı
w.

Varlık Çekirdeğini Kullanan Oturum Çekirdeği


Bağımlılık İçitimi
Devingen Sorulama
VarlıkYöneticisi
ww

Diğer Yenilikler
Kap Dışında Test Edilebilme
Nesne/İlişkisel Eşleme
Geliştirilmiş EJB QL
Kaynaklar
Günümüz EJB Modeli

Kurumsal Java Çekirdekleri (Enterprise JavaBeans, EJB) Mimarisi, bileşen tabanlı

m
ve dağıtımlı kurumsal uygulamaların geliştirilmesi ve yaygınlaştırılmasına yönelik bir
J2EE mimarisidir. EJB genel olarak güçlü ve birçok hizmete olanak sağlayan bir
mimaridir. Bu mimari kullanılarak geliştirilmiş yazılımlar; ölçeklenebilir, birim işlem

o
yeteneğine sahip, güvenli ve dayanıklı olup kurumların önemli gereksinimlerini
karşılayacak nitelikte, çok kullanıcılı uygulamalardır. Bu gereksinimler EJB çalışma

i.c
zamanı ortamında EJB kabı(container) servisleri tarafından karşılanmaktadır. Yani
eşanlı veri erişimi ve güvenlik desteği otomatik olarak EJB kabı tarafından tüm
kurumsal çekirdekler(beans) için sağlanmaktadır. EJB ile oluşturulan uygulamalar, bir
kez yazıldıktan sonra EJB belirtimlerine uygun herhangi bir sunucu ile kullanılabilir.

dil
EJB, ilk olarak CORBA mimarisinin karmaşıklıklarına bir çözüm sunma vaadi ile
ortaya çıkar. Bu yeni mimari, birçok ana düzenleme ve şişirilmiş temel özellikleri ile
kısa zamanda J2EE’nin kalbi olur. EJB mimarisi ilk anda birçok kullanıcı tarafından
sevilir ve uygulama geliştiriminde tercih edilir. Ancak EJB mimarisinin bu güçlü ve
va
birçok özelliği içinde barındıran yapısı ile uygulama geliştirenler kişiler açısından
geliştirdikleri projeler için bekledikleri etkiyi vermez. Çünkü EJB ile uygulama
geliştirmek, beklenilen kadar kolay olmakla beraber tüm EJB belirtimleri ile birlikte
daha da karmaşık bir yapı sunmaktadır.
ja

Bu modelde karşılaşılan zorlular:

• Kurumsal çekirdek sınıfları, bir arayüzün gerçekleştirimi olduğundan arayüz


w.

içinde tanımlı tüm metotlar (callback metods), kullanılsın kullanılmasın,


gerçekleştirilmek(implementation) (“ejbActivate”, “ejbPassivate”… gibi) zorundadır.
Bu da kod karmaşıklığına yol açmaktadır.
• Bileşen arayüzlerinin “EJBObject” ve “EJBLocalObject" sınıflarını
ww

gerçekleştirmek zorunda olunması ve gereksiz aykırı durumları ele alma zorunluluğu


• Tüm üreteç arayüzlerinin “javax.ejb.EJBHome” arayüzünden genişletilmek
zorunda olması
• Yayımlama belirtim belgesi (deployment descriptor) hazırlamanın karmaşıklığı
ve bu belgeyi hazırlarken hata yapma olasılığının fazla olması
• EJB modeli taban alınarak kap tabanlı kalıcılık (Container-Managed
Persistence) modelinin geliştirim zorluğu ve yönetiminin karmaşıklığı

m
• EJB sorgu dilinin çok kısıtlı olması ve bu sorgu dilinde birçok temel özelliğin
olmaması; mesela veritabanı dizisi ile standart olarak bir birincil anahtar
tanımlayamama…
• EJB bileşenlerininde kalıtım (inheritance) ve çokbiçimlilik (polymorphism)

o
kullanımına getirilen kısıtlar yüzünden uygulamanın nesneye yönelik yaklaşımdan
uzaklaşması

i.c
• EJB modüllerinin kap dışında test edilememesi ve kap içinde hata ayıklamanın
ise uygulama geliştirenler için kâbusa dönüşmesi
• EJB mimarisinin karmaşık bir yapı içermesi, bakımı ve yürütmesinin zorluğu
• EJB nesnelerine erişmek veya bu nesneleri yerleştirmek için JNDI’ın çok ufak

dil
ayrıntılarının bilinmek zorunda olması… JNDI bazı kod geliştirenler için hantal
ve sezgisel olmayan (non-intuitive) bir yapı olarak ortaya çıkmaktadır.

Neden EJB 3.0 ?


va
EJB 3.0 teknolojisinin misyonu karmaşık EJB gereksinimlerini çıkarmak ve
mümkün olduğunca eski basit Java nesnelerine (Plain Old Java Objects) dönerek
uygulama geliştirebilmektir. Bu teknolojide, kaptan ziyade çekirdeğin tasarımına
odaklanılmış ve kabın bugünkü görünümü değiştirilmiştir. Sonuçta çekirdek ve kabın
ja

rolleri yeniden tasarlanmıştır.

J2EE geliştiricilerinin, özel açıklamalar kullanarak çekirdeğin özelliklerini


tanımlayabilmeleri ve bu özel açıklamalar sayesinde arayüz kütüklerinin üretilmesini,
w.

yaygınlaştırma belirtim belgesine olan gereksiniminin ortadan kaldırılmasını


sağlamıştır.
ww
EJB 3.0 Teknolojisinin Ana Amaçları:
• EJB geliştirimini basitleştirmek

m
◊ Kod içine yazılan özel açıklamalar (annotation) ve ara verilerle
(metadata) kod üretimini sağlayıp uygulama geliştiren kişinin daha az
kod yazmasını sağlamak ve yaygınlaştırma belirtim belgesi ortadan
kaldırmak

o
◊ EJB içeriğini eski basit Java nesnelerine (POJO) ya da Java
çekirdeklerine (JavaBeans) benzetebilmek

i.c
◊ Varlık çekirdekleri(entity beans) ve oturum çekirdekleri(session beans)
için oluşturulan EJB bileşen arayüzlerinin kaldırılmak… Bu yeni
sürümde tanımlanan oturum çekirdekleri için gerekli iş arayüzleri, eski
basit Java arayüzleri (POJI) olacaklar, dolayısıyla EJBLocalObject,


EJBObject veya
dil
java.rmi.Remote
yapmak zorunda olunmayacak.
arayüzlerinin

Varlık çekirdekleri için bir arayüz oluşturmamak…


gerçekleştirimini

◊ Çevresel bağımlılıkların kapsamı ve JNDI erişimlerinin ek açıklamaların


va
kullanımıyla gerçekleştirimi, basit “lookup” işleyişi, bağımlılık sebebi
olan kaynakların EJB içine eklenmesi, kurumsal çekirdek türlerinin
sadeleştirilmesi…
• Kap tabanlı kalıcılığın sadeleştirilmesi
◊ Kalıtım ve çokbiçimliliği içeren yalın bir modelleme desteği
ja

◊ Nesne ilişkisel eşlemede (Object/Relational mapping) Java kod içi özel


açıklamaların kullanımı
◊ Varlık çekirdeklerinin kap tabanlı kalıcılıkla düşünülmesi
w.

◊ EJB QL kullanımının artmasının sağlamak için, geliştirilmesi. Buna göre


açık iç ve dış birleştirme işlemleri, yığın günleme ve silme, alt sorgu ve
gruplamanın (group by) kullanımı… Dinamik sorgu yeteneğine ek
olarak veritabanı şemalarından bağımsız doğal SQL sorgu desteği
ww

sağlamaktadır.
• Aykırı durum ele alma gereksinimlerinin azaltılması
• Üreteç (home) arayüz ve bu arayüz metotlarının kullanılsa da kullanılmasa da
gerçekleştirimlerinin çıkartılması
• Kap dışında da test edilebilme yeteneği
Bazı gözlemciler EJB 3.0’ın Sun firması için radikal bir değişim olduğunu, diğer
açık kaynakların, Spring Java uygulama iskeleti(framework) gibi başarılı

m
uygulamalara yanıt niteliğinde ortaya çıktığını savundular. Ancak halen Spring ve
Hibernate açık kaynakları ile kıyaslanınca EJB 3.0 teknolojisinin yeterince iyi
olmadığı görülmektedir.

o
Java 5’te Tanımlanan Özel Açıklamalar (Metadata Annotations)

i.c
Java 5, (J2SE 1.5) dile getirdiği yeni açıklama özellikleri ile tanıtıldı. Açıklama
satırlarına getirilen yeni özellikte, özel açıklamalar tanımlanabiliyor bunlar açıklama
alanları, metotlar, sınıflar… vb. olabiliyor. Açıklama satırları doğrudan programın
yapısını etkilemiyor ancak araçlar sayesinde (derleme zamanında ya da çalışma

dil
zamanında) bu açıklamalar taranıp yaygınlaştırma belirtimi (deployment descriptor)
kütüğü gibi veya zorunlu istenilen çalışma zamanı davranışları (EJB bileşeninin
durumlu (stateful) hali gibi) sonradan üretiliyor. Java 5’de bulunan açıklama satırları,
kaynak kodu belirli araçlarla (derleyici veya IDE araçları gibi) parçalara ayrılarak veya
uygulama programı arayüzlerine(API) eklenen özelliklerle inceliyor. Açıklama
va
tanımları sadece kaynak kodu katmanı, derlenmiş sınıf katmanı ya da çalışma
zamanında geçerli olabiliyor. EJB 3.0’ın yeni taslağında kullanılan tüm ek açıklamalar
için çalışma zamanı saklama politikası (RetentionPolicy of RUNTIME) geçerlidir.
Tanımlanan bu özel açıklamaların bulunduğu sınıflar için ayrılan bellek alanlarını az
ja

da olsa artırıyor fakat kap (container) üreticilerinin ve araç üreticilerinin işini oldukça
kolaylaştırıyor.

EJB 3.0 içinde de çeşitli özel açıklama türleri kullanılmaktadır.


w.

• Çekirdek tür belirtimleri (@Stateless, @Stateful, @MessageDriven, @Entity)


• Çekirdeğe uzaktan mı yoksa yerel mi erişilebileceğinin tespiti (@Remote,
@Local)
ww

• Birim işlem nitelikleri (@TransactionAttribute)


• Güvenlik ve metot izinleri(@MethodPermissions, @Unchecked,
@SecurityRoles)
… vb birçok buna benzen özel açıklama kullanılmaktadır.
Birçok durumda açık özel açıklamalar yazmak yerine öndeğer olarak atanan
değerler kullanılmaktadır. Bu durumda uygulama geliştiren kişi özel açıklamayla
birlikte öndeğer olarak atanan değerleri tekrar tekrar yazmak zorunda değildir.
(Mesela @Entity açıklaması olan varlık çekirdeği türünü CMP olarak ayrıca

m
belirtmeye gerek yoktur, çünkü öndeğer olarak CMP seçilmiş kabul edilir.) Bu tür
öndeğerler kurumsal çekirdeklerin açıklamalarını çok basit hale getirmektedir. Bu tür
öndeğerler EJB 3.0 teknolojisine yol gösteren “aykırı durumla kodlama” (“coding by
exception”) yaklaşımını tanımlamaktadır. Amaç öndeğerler yeterli olmadığı zaman,

o
geliştiricilerin kodlamak zorunda oldukları basitleştirmektir.

i.c
Durumsuz Oturum Çekirdeği (Stateless Session Bean)
Bu bölümde bir örnek üzerinden EJB 2.1 ve EJB 3.0 teknolojileri arasındaki farklar
anlatılacaktır. DonusturucuBean, uzaktan erişilebilen bir kurumsal çekirdek olup
herhangi bir dövizi Dolar’dan TL’ye ve TL’den Euro’ya dönüştürmektedir.
EJB 2.1 dil
Oturum Çekirdeği yaratabilmek için geliştirici, öncelikle aşağıdaki kodları yazmak
zorundadır:
ƒ Uzak istemcinin erişebilmesi için oturum çekirdeğinin yaşam döngüsü
va
metotlarını tanımlayan bir üreteç arayüzü (home interface)
ƒ Uzak istemcinin erişebilmesi için oturum çekirdeğinin iş metotlarının
tanımlandığı uzak arayüz (remote interface)
ƒ İçinde üreteç ve uzak arayüzdeki metotların gerçekleştiriminin yapıldığı
ja

çekirdek sınıfı
ƒ Çekirdeğin bilgilerinin tanımlandığı, adı ve türü gibi, yaygınlaştırma belirtim
belgesi
w.

Üreteç Arayüzü (Home Interface)

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
ww

public interface DonusturucuHome extends EJBHome {


Donusturucu create() throws RemoteException,
CreateException;
}
Yapılması gereken zorunlu işlemler:
• Tüm üreteç arayüzleri javax.ejb.EJBHome arayüzünü genişletmek (extends)

m
zorundadırlar.
• Üreteç arayüzü içinde “create” ve “remote” gibi bir ya da birçok yaşam
döngüsü ile ilgili metodları tanımlamak gerekir. Ayrıca bu metotların
“RemoteException” ve “CreateException” aykırı durumlarını fırlatmaları gerekir.

o
Uzak Arayüz(Remote Interface)

i.c
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
import java.math.*;

public interface Donusturucu extends EJBObject {

}
dil
public BigDecimal dolardanYeniTLye(BigDecimal dolar)
throws RemoteException;
public BigDecimal yeniTLdenEuroya(BigDecimal yeniTL)
throws RemoteException;

Yapılması gereken zorunlu işlemler:


va
• Bütün uzak arayüzler javax.ejb.EJBObject arayüzünden genişletilmek
zorundadır.
• Uzak arayüzünde çekirdek sınıfı içinde gerçekleştirimi bulunan metotların
tanımları bulunur ve tüm uzak arayüzler “RemoteException” fırlatmak
ja

zorundadır.
w.
ww
Çekirdek Sınıfı(Bean Class)

m
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import java.math.*;

public class DonusturucuBean implements SessionBean {

o
BigDecimal yeniTLOrani;
BigDecimal euroOrani;

i.c
public BigDecimal dolardanYeniTLye(BigDecimal dolar) {
BigDecimal sonuc = dolar.multiply(yeniTLOrani);
return sonuc.setScale(2,BigDecimal.ROUND_UP);
}

public BigDecimal yeniTLdenEuroya(BigDecimal yeniTL) {


BigDecimal sonuc = yeniTL.multiply(euroOrani);
return sonuc.setScale(2,BigDecimal.ROUND_UP);
}

}
dil
public DonusturucuBean() {
yeniTLOrani = new BigDecimal("0.66");
euroOrani = new BigDecimal("1.85");

public void ejbCreate() {}


public void ejbRemove() {}
va
public void ejbActivate() {}
public void ejbPassivate() {}

• Bütün oturum çekirdekleri “javax.ejb.SessionBean” arayüzünü ve kullanılsın,


kullanılmasın bu arayüz içinde bulunan “ejbCreate”, “ejbRemove”, “ejbActivate”,
“ejbPassivate” ve “setSessionContext” sınıflarını gerçekleştirmek zorundadırlar.
ja

Yaygınlaştırma Belirtim Belgesi(Deployment Descriptor)

<?xml version="1.0" encoding="UTF-8"?>


w.

<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" ...">


<display-name>DonusturucuJAR</display-name>
<enterprise-beans>
<session>
<ejb-name>DonusturucuBean</ejb-name>
<home>donusturucu.DonusturucuHome</home>
<remote>donusturucu.Donusturucu</remote>
ww

<ejb-class>donusturucu.DonusturucuBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
<security-identity>
<use-caller-identity/>
</security-identity>
</session>
</enterprise-beans>
</ejb-jar>
Yaygınlaştırma belirtim belgesi, çekirdeğin ismi ve bu çekirdeğe ait arayüzlerin

m
isimleri gibi çekirdek hakkındaki temel bilgileri içeren bir kütüktür ve yazılmak
zorundadır.

İstemci Test Sınıfı

o
import donusturucu.Donusturucu;
import donusturucu.DonusturucuHome;

i.c
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import java.math.BigDecimal;

public class DonusturucuClient {


public static void main(String[] args) {
try {
dil
Context c = getInitialContext();
Object o = c.lookup("Donusturucu");
DonusturucuHome home =
(DonusturucuHome) PortableRemoteObject.narrow(o,
DonusturucuHome.class);

Donusturucu dovizDonusturucu = home.create();


va
BigDecimal param = new BigDecimal("100.00");
BigDecimal miktar = dovizDonusturucu. dolardanYeniTLye(param);

System.out.println(miktar);
miktar = dovizDonusturucu.yeniTLdenEuroya(param);
System.out.println(miktar);
ja

System.exit(0);
} catch (Exception ex) {
System.err.println("Hata!");
ex.printStackTrace();
}
}
w.

}EJB 3.0
ww
EJB 3.0
EJB 3.0 teknolojisi ile bir oturum çekirdeği oluşturabilmek için, uygulama geliştiren

m
kişi uygun açıklamalar (metadata annotations) kullanarak eski basit java nesnelerine
(POJO) uygun bir çekirdek sınıfı yazması yeterlidir. Bu çekirdek sınıfı için ayrıca bir
de iş arayüzü kendiliğinden çekirdek sınıfı içine yazılan açıklamalar yoluyla
oluşturulmalı ya da ayrıca yazılmalıdır.

o
Yukarıda EJB 2.1’de anlatılan durumsuz oturum çekirdeği örneğinin EJB 3.0
biçimi aşağıda açıklanmaktadır.

i.c
Uygulama geliştiren kişi oturum çekirdeği yazmak için uygun özel ek açıklamalar
kullanarak bir çekirdek sınıfı yazmalıdır:
Çekirdek Sınıfı

@Stateless @Remote public class DonusturucuBean {

BigDecimal yeniTLOrani;
BigDecimal euroOrani;
dil
public BigDecimal dolardanYeniTLye(BigDecimal dolar) {
BigDecimal sonuc = dolar.multiply(yeniTLOrani);
return sonuc.setScale(2,BigDecimal.ROUND_UP);
}
va
public BigDecimal yeniTLdenEuroya(BigDecimal yeniTL) {
BigDecimal sonuc = yeniTL.multiply(euroOrani);
return sonuc.setScale(2,BigDecimal.ROUND_UP);
}
public DonusturucuBean() {
yeniTLOrani = new BigDecimal("0.66");
euroOrani = new BigDecimal("1.85");
ja

}
w.

Çekirdek Arayüzü

public interface Donusturucu {


BigDecimal dolardanYeniTLye (BigDecimal dolar);
BigDecimal yeniTLdenEuroya (BigDecimal yeniTL);
}
ww

Çekirdek sınıfı içinde kullanılan özel açıklamalar (annotations) “@Stateless” and


“@Remote” olarak yukarıdaki kodda görülmektedir. Özellikle dikkati çeken
özelliklerden birisi hiçbir üreteç ve uzak arayüz sınıflarının veya yaygınlaştırma
belirtim belgesinin yazılmaması gerekmemektedir. Gerekli olan tek arayüz, iş
arayüzüdür. Bu arayüz hiç bir sınıfın gerçekleştirimini yapmak ve herhangi bir aykırı
durum (“java.rmi.Remote” ve “java.rmi.CreateException” gibi…) fırlatmak zorunda
değildir dolayısıyla bu arayüz eski basit java arayüzü (POJI) olmalıdır. İş arayüzü
oluşturan kişi bu sınıfı kendisi yazabileceği gibi özel açıklamalarla kendiliğinden

m
üretilmesi sağlanabilir.
EJB 3.0 çekirdek sınıfı eski basit java nesneleri gibi kodlanırlar, ayrıca
“javax.ejb.SessionBean” arayüzü gerçekleştirimini yapmak zorunda da değildirler.
Bunun sonucu olarak geliştiren kişi “ejbCreate”, “ejbRemove”, “ejbActivate”,

o
“ejbPassivate” ve “setSessionContext” metotlarını gerçekleştirmek zorunda
kalmayacaktır. Ancak eğer uygulama geliştiren kişi gerekirse bu metodu/metotları

i.c
gerçekleştirebilir, dolayısıyla EJB 2.1 teknolojisinde olduğu gibi, kap bu metotları
çağırabilir.

İstemci Test Sınıfı

import donusturucu.Donusturucu;
import java.math.BigDecimal;
dil
@Session public class DonusturucuClient {
@Inject Donusturucu
va
Donusturucu dovizDonusturucu;

BigDecimal param = new BigDecimal("100.00");


BigDecimal miktar = dovizDonusturucu.dolardanYeniTLye(param);

...
}
ja

Nesnelerin ve kaynakların başvurularına(references) ulaşmak için kurumsal


w.

çekirdek içinde JNDI’ya ihtiyaç yoktur. Bunun yerine uygulama geliştiren kişi özel
açıklamalarla kaynaklara ulaşabilmektedir. Bu özel açıklamalara bağımlılık
açıklamaları (dependency annotations) denmektedir. Çünkü uygulama geliştiren kişi
bu açıklamaları kaynak ve nesne ortamındaki kurumsal çekirdeklere olan bağımlılığı
ww

temsil etmektedirler. Bu özel açıklama “@Inject” olup istemci sınıfı içinde


kullanıldığında kap, başvurular sayesinde kurumsal çekirdeklere erişimi sağlar.
Böylece kurumsal çekirdeğin bulunduğu kaynak ve diğer nesnelerin bağımlılık içitimi
(dependency injection) olur. Bağımlılık içitimi (dependency injection) geliştiricinin
kodlamak zorunda olduğu kaynak ve çevresel başvuruları elde etme işlemini
sadeleştirmektedir. JNDI “lookup” ihtiyaç olmamasına rağmen istenilirse kullanılabilir.
Kap Tabanlı Kalıcılık ile Varlık Çekirdeği
(Entity Bean with Container-Managed Persistence)

m
Bu bölümde bir OyuncuBean ve TakimBean çekirdek sınıflarını içeren varlık
çekirdeği örneği vasıtasıyla EJB 2.1 ve EJB 3.0 arasındaki farklar anlatılacaktır. Bu

o
örnekte OyuncuBean, kap tabanlı kalıcılık kullanmaktadır. Bu çekirdek ve TakimBean
çekirdek sınıfı arasında birçoğa birçok ilişki bulunmaktadır. Bir oyuncu birçok takımda
oynayabilmektedir ve bir takımda birçok oyuncu oynayabilmektedir.

i.c
EJB 2.1
• Bir varlık çekirdeği oluşturabilmek için aşağıdaki kodlar yazılmalıdır:
• Yerel istemciler tarafından çağrılabilecek varlık çekirdeği sınıfının yaşam
döngüsü metotlarını içeren bir yerel üreteç arayüzü
• dil
Varlık çekirdeğinin iş ve erişim metotlarını içeren ve yerel istemciler tarafından
çağrılabilen bir yerel arayüz
• Üreteç ve yerel arayüzlerinde tanımları bulunan metotların
gerçekleştirimlerinin bulunduğu çekirdek sınıfı
va
• Çekirdek sınıfının ismini, kalıcılık türünü ve soyutlama şeması gibi bilgilerin
bulunduğu yaygınlaştırma belirtim belgesi
Yerel Üreteç Arayüzü

package team;
ja

import java.util.*;
import javax.ejb.*;

public interface LocalOyuncuHome extends EJBLocalHome {


w.

public LocalOyuncu create (String kimlik, String ad,


String konum, double ucret)
throws CreateException;

public LocalOyuncu findByPrimaryKey (String kimlik)


throws FinderException;
ww

public Collection findByKonum(String konum)


throws FinderException;
...
public Collection findBySpor(String spor)
throws FinderException;
...
}
Bütün yerel üreteç arayüzleri “javax.ejb.EJBLocalHome” arayüzünü
gerçekleştirmek zorundadır. Bu yüzden bu arayüzde bulunan yaşam döngüsü

m
metotları da kullanılsın ya da kullanılmasın gerçekleştirilmelidir. “ejbCreate” işlevi
ayrıca “CreateException” aykırı durumunu fırlatmak zorundadırlar.
Üreteç arayüzünde ayrıca bulan (finder) metotların tanımları bulunur. Varlık
çekirdeği içinde “findByPrimaryKey” metodu tanımlanmak zorundadır. Bunun dışında

o
kullanılan bulan metotlar için EJB QL sorguları yazılmak zorundadır. Tüm yazılan
bulan metotlar “FinderException” fırlatmak zorundadırlar.

i.c
Yerel Arayüz

package team;

import java.util.*;
import javax.ejb.*;
dil
public interface LocalOyuncu extends EJBLocalObject {

public String getOyuncuKimlik();


public String getAd();
va
public String getKonum();
public double getUcret();
public Collection getTakim();

public Collection getLig() throws FinderException;


public Collection getSpor() throws FinderException;
}
ja

Bütün yerel arayüzler “javax.ejb.EJBLocalObject” arayüzünden genişletilmek


zorundadır.
w.

Yerel istemcinin çağırabileceği erişim metotları (get/set) tanımlanır. Bu metotlar,


yaygınlaştırma belirtimi belgesinde tanımlanan, çekirdeğin kalıcı alanlarına
(persistent field) ve ilişki alanlarına(relationship field) erişimi sağlar.
ww
Çekirdek Sınıfı

m
public abstract class OyuncuBean implements EntityBean {
private EntityContext context;

public abstract String getOyuncuKimlik();

o
public abstract void setOyuncuKimlik(String kimlik);
...
public abstract Collection getTakim();
public abstract void setTakim(Collection takim);

i.c
...
public abstract Collection ejbSelectLig(LocalOyuncu oyuncu)
throws FinderException;
...
public Collection getLig() throws FinderException {
LocalOyuncu oyuncu =
(takim.LocalOyuncu)context.getEJBLocalObject();
return ejbSelectLig(oyuncu);
}
... dil
public String ejbCreate (String kimlik, String ad,
String konum, double ucret) throws CreateException {

setOyuncuKimlik(kimlik);
setAd(ad);
setKonum(konum);
va
setUcret(ucret);
return null;
}
public void ejbPostCreate(String kimlik, String ad, String konum,
double ucret) throws CreateException {
}
...
ja

ƒ Tüm varlık çekirdek sınıfları “javax.ejb.EntityBean” arayüzünü gerçekleştirmek


zorundadır. Buna bağlı olarak bu arayüz içinde tanımları bulunan tüm metotların
w.

(“ejbRemove”, “ejbActivate”, “ejbPassivate”, “ejbLoad”, “ejbStore”, “setEntityContext”


ve “unsetEntityContext” gibi…) kullanılsın ya da kullanılmasın gerçekleştirimini
yapmak zorundadırlar.
ƒ “ejbCreate” ve “ejbPostCreate” gibi metotların gerçekleştirimini yapmak
ww

zorundadırlar.
Yaygınlaştırma Belirtim Belgesi

m
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" ...">
<display-name>TakimJAR</display-name>
<enterprise-beans>

o
<entity>
<ejb-name>OyuncuBean</ejb-name>
<local-home>takim.LocalOyuncuHome</local-home>

i.c
<local>takim.LocalOyuncu</local>
<ejb-class>takim.OyuncuBean</ejb-class>
<persistence-type>Container</persistence-type>
...
<abstract-schema-name>Oyuncu</abstract-schema-name>
<cmp-field>
dil
<description>no description</description>
<field-name>position</field-name>
</cmp-field>
...
<primkey-field>OyuncuKimlik</primkey-field>
va
...
<query>
<query-method>
<method-name>findAll</method-name>
<method-params/>
ja

</query-method>
<ejb-ql>select object(p) from Oyuncu p</ejb-ql>
</query>
...
w.

<query>
<query-method>
<method-name>ejbSelectLig</method-name>
<method-params>
ww

<method-param>takim.LocalOyuncu</method-param>
</method-param>
</query-method>
<result-type-mapping>Local</result-type-mapping>
<ejb-ql>select distinct t.lig
from Oyuncu p, in (p.takim) as t
where p = ?1</ejb-ql>
</query>
...
</entity>
</enterprise-beans>

m
<relationships>
<ejb-relation>
<ejb-relationship-role>
<multiplicity>Many</multiplicity>

o
<relationship-role-source>
<ejb-name>TakimBean</ejb-name>
</relationship-role-source>

i.c
<cmr-field>
<cmr-field-name>Oyuncu</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
dil
<multiplicity>Many</multiplicity>
<relationship-role-source>
<ejb-name>OyuncuBean</ejb-name>
</relationship-role-source>
va
<cmr-field>
<cmr-field-name>takim</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>
ja

</ejb-relation>
...
</ejb-relationship-role>
</ejb-relation>
w.

</relationships>
</ejb-jar>

Açıkça görülmektedir ki varlık çekirdeği için oluşturulan belge ile oturum çekirdeği
arasında uzunluk ve karmaşıklık olarak büyük bir fark vardır. Varlık çekirdeklerinin
ww

yaygınlaştırma belirtim belgesi hazırlanırken çekirdeğe ait temel bilgilerin yanı sıra
soyutlama şemayı da (abstract schema) içermektedir. Bu şema içerisinde çekirdeğin
kap tabanlı ilişki alanları, oyuncular ve takımlar arasındaki birçoğa birçok ilişkilerin
belirtimleri bulunmaktadır. Bunlara ek olarak yaygınlaştırma belirtimi belgesi EJB QL
sorgularını ve seçme metotlarını (select methods) da içermektedir.
Üreteç arayüzü içinde tanımlanan bulan (finder) metotlar için oluşturulan sorgu

m
cümlecikleri yaygınlaştırma belirtim belgesi içinde tanımlanmaktadır. Ancak bu
sorgular kullanılan EJB QL dilinin çok gelişmiş olmadığı için karmaşık sorguların
yazılmasına imkân vermemektedir. EJB 2.1 teknolojisinde kullanılan örnek bir EJB
QL sorgusu aşağıdaki gibidir:

o
SELECT DISTINCT OBJECT(p) FROM Oyuncu p WHERE p.position = ?1

i.c
EJB 3.0
EJB 3.0 belirtiminin bir parçası olan EJB kalıcılık teknolojisi, halen tüm Java
platformları için yenilenmektedir. Yeni Java kalıcılık uygulama programı arayüzü
(API) Java platformunda, kalıcılık gerçekleştirimi için yeni ve tek bir örnek olacaktır.

dil
Bu yeni model J2EE 5.0 oluştuğunda, halen 2006 yılının ilk çeyreği olarak planlanan
tarihte yürürlüğe girecektir. Var olan kap tabanlı kalıcılık uygulamaları değişmeden
işlemeye devam edecek çünkü EJB teknolojisindeki kap tabanlı kalıcılık işlevi
desteklenmeye devam edilecek aynı zamanda geliştirilmeye de devam edilecek. Yeni
API ile var olan uygulamalar terk edilmeyecek. EJB uzman ekibi uygulama
va
geliştirenlerin EJB teknolojisini ve yeni API’yı aynı uygulamada kullanabilmelerini
sağlamak için çalışmaktadır.
ja
w.
ww
Çekirdek Sınıfı

@Entity public class OyuncuBean {

m
private Long OyuncuKimlik;
private String ad;
private String position;
private double ucret;
private Collection takim;

o
public OyuncuBean() {}

@id(generate=AUTO) public Long getOyuncuKimlik() {


return kimlik;

i.c
}

public String setOyuncuKimlik(Long kimlik) {


this kimlik=kimlik;
}

public String getAd() {


return ad;
}

public String setAd() {

}
this ad= ad;
dil
...
public Collection getTakim() {
return takim;
va
}

public Collection setTakim(Collection takim) {


this takim=takim;
}
...
ja

“@Entity” özel açıklaması ilgili sınıfın varlık çekirdeği olduğunu işaret eder.
Yukarıda da görüldüğü gibi varlık çekirdek sınıfı da EJB 3.0 teknolojisinde oturum
çekirdeğinde olduğu gibi üreteç arayüzü, uzak arayüz ve yaygınlaştırma belirtim
belgesi içermez. Aslında varlık çekirdeği için iş arayüzü bile gerekmez. Çekirdek
w.

sınıfı “javax.ejb.EntityBean” gibi bir arayüzü gerçekleştiren bir sınıf olmanın tersine
POJO olarak kodlanan bir çekirdek sınıfıdır. Bu “new()” işlemiyle, varlık çekirdeği
nesnesinin basit bir şekilde yaratılabileceği anlamına gelmektedir. Ek olarak
ww

uygulama geliştiren kişi çekirdek sınıfı içinde “ejbRemove”, “ejbActivate”,


“ejbPassivate” ve “ejbLoad” gibi metotları gerçekleştirmek zorunda değildir.
EJB 3.0 teknolojisinde varlık çekirdek sınıfı somut bir sınıftır. Yukarıda
OyuncuBean örneğinde de görüldüğü üzere varlık çekirdeği soyut olmayan, gizli
nitelikleri bulunan bir sınıftır. Bu nitelikler çekirdeğin kalıcılık alanlarını temsil
etmektedirler. Kalıcılık alanlarına erişim, EJB 2.1’de de olduğu gibi, “get” ve “set” gibi
metotlarla sağlanmaktadır. Ancak EJB 3.0’da bu metotlar somut metotlardır. Ek
olarak, EJB 3.0’daki bu metotlar, önceden mümkün olmayan, mantık özelliği

m
içermektedir. Bu alanların geçerliliği gibi işlemler için yararlı olacaktır. Bir diğer
gelişme kalıcılık alanlarına erişimin sadece “getter” ve “setter” metotlarıyla olmayıp
erişim sınıfların iş metotlarıyla da yapılabilmektedir. Ancak bu metotlara sadece
sınıfın kendisi erişebilecek başka bir deyişle nesnenin niteliklerini sınıf dışına

o
açmamak şartıyla bu metotlar gerçekleştirilebilmektedir. Bu nesne niteliklerinin gizli
olmasından kaynaklanmaktadır. EJB 3.0’da ayrıca parametresiz bir yapıcı

i.c
metot(constructor) tanımlanmak zorunludur.
@Id özel açıklaması birincil anahtar için kullanılmaktadır. Bu öğe-değer çifti
“generate=AUTO” EJB kabına birincil anahtara özel veritabanı için uygulamada
kullanılabilecek uygun bir strateji izlemesi gerektiğini anlatmaktadır. @Id özel

dil
açıklaması nesne ilişkisel eşleme için EJB 3.0 belirtiminde tanımlanmıştır.

Varlık Çekirdeğini Kullanan Oturum Çekirdeği


va
@Stateless public class RosterBean {
@Inject EntityManager em;

public Long createOyuncu(OyuncuBean oyuncu) {


em.create(oyuncu);
return oyuncu.getOyuncuKimlik();

public OyuncuBean findByOyuncuKimlik(Long oyuncuKimlik) {


ja

return (OyuncuBean) em.find("Oyuncu", oyuncuKimlik);


}
...
}
w.

EJB 3.0 sürümü ile kodları bu kadar kısa ve basit hale getiren iki özellik bağımlılık
içitimi(dependency injection) ve varlık yöneticisidir(EntityManager).
ww
Bağımlılık İçitimi(Dependency Injection)
Bağımlılık içitimi, geliştirilen bu yeni teknolojideki temel bir değişiği yansıtmakla

m
birlikte değişik kurumsal çekirdeğin sahip olduğu ortamda bulunan kaynak veya diğer
nesne bağımlılıklarının içe gömülmesidir. Bu da “@Inject” özel açıklaması ile
sağlanmaktadır. Bağımlılık içitimi EJB mimarisindeki temel değişimi yansıtmaktadır.
EJB mimarisinin önceki sürümleri geliştirici EJB kabının sınıfları ve arayüz

o
gerçekleştirimi açısından şartlarına uymaya zorlamaktaydı. Bağımlılık içitiminde ise
çekirdek EJB kabına ne istediğini söylüyor sonar kap bu gereksinimleri karşılıyor.

i.c
RosterBean sınıfında “@Inject” özel açıklaması EJB kabına oturum çekirdeğinin
VarlıkYöneticisi (EntityManager) nesnesine ihtiyacı olduğunu anlatmaktadır. Genel
olarak, bir bağımlılık özel açıklaması sınıf’ın ortamında ihtiyaç duyulan kaynak veya

dil
nesneyi daha önce kaynak ya da nesneye ulaşmakta kullanılan ismi tespit etmeyi
sağlıyor. “@Inject” özel açıklaması tüm gerekli öğelerin özel açıklamaları
tanımlandığında kullanılabilir. Bağımlılık içitimi için kullanılabilecek diğer iki özel
açıklamadan biri kaynak üzerindeki bağımlılığı tanımlayan “@Resource” olup diğeri
va
de oturum çekirdeği üzerindeki bağımlılığı tanımlayan “@EJB” açıklamasıdır.
Oturum çekirdeği iş metodu kullanımını elde etmeden önce ihtiyaç duyulan
kaynak ya da nesne başvurusunu zerk etmek EJB kabının sorumluluğudur. Bu
genellikle EJB kabının “setSessionContext” metodunu çağırdığı zamanda olmaktadır.
ja

Devingen Sorulama (Dynamic Lookup)


Kaynak yerleştiriminde bağımlılık içitimi tek yol değildir. EJB 3.0 belirtimi ayrıca
w.

devingen sorgulama yeteneğine de sahiptir. Bu yetenek “javax.ejb.EJBContext”


arayüzü içerisindeki “lookup” metodu ile sağlanmaktadır.
ww
VarlıkYöneticisi (EntityManager)
EJB 3.0 teknolojisi içerisindeki kalıcılık modeli varlık çekirdekleri kap tabanlı

m
kalıcılık için sadeleştirilmiştir. EJB 3.0 mimarisi içerisindeki yeni bir uygulama
programı arayüzü (API) ve basitleştirilmiş kalıcılık modeli olan VarlıkYöneticisi türü
hariç üreteç arayüzüne benzemektedir ve varlık çekirdeğinin durumunu yönetmek için
kullanılmaktadır. Varlık çekirdeğini yönetim durumunda tutan (kalıcılık bağlamı

o
“persistence context” olarak adlandırılan) “create” ve varlık çekirdeğinin kalıcılık
bağlamından çıkartılmasını sağlayan “remove” gibi birçok yaşam döngüsü metotları

i.c
API içinde tanımlanmıştır. Yönetim durumundaki çekirdek nesnesinin temsil ettiği veri
birim işlem (transaction) sonunda veri tabanına eklenir. Varlık yöneticisi ayrıca
veritabanı ve kalıcılık bağlamı zamanuyumlamasını sağlayan “flush” metoduna
sahiptir. Birim işlem sonlanmadan önce, “flush” devre dışı iken yönetilen varlık

dil
çekirdeği nesnesinin temsil ettiği veri veritabanına kaydedilir. birim işlem sonunda ve
“flush” boyunca veritabanında neyin nereye yerleşeceği EJB 3.0’ın yeni bir özelliği
olan nesne ilişkisel eşleme (Object/Relational mapping) belirtimlerine bağlıdır.
VarlıkYöneticisinde tanımlı önemli diğer metotar ise varlık çekirdeği nesnesini birincil
va
anahtara göre bulan “find” ve şu anki kalıcılık modeli ile ayrılmış varlık çekirdeği
nesnesinin durumalarını birleştiren “merge”’dir. EJB 3.0 mimarisindeki varlık çekirdeği
modeli, varlık çekirdeği nesnelerini ayırmaya(detached) izin vermektedir. Bu ayrım
birim işlem sonunda gerçekleşir. Ayrılmış nesneler yaratıldıkları birim işlem bağlamı
dışında da geçerli olmaktadırlar. Bu özellik geliştiricinin çekirdek nesnesini bir diğer
ja

uygulama katmanını için bit serisine dönüştürülür (serialize). Bundan önceki varlık
çekirdekleri bit serisi haline dönüştürülemiyordu. Geliştiriciler veri transfer nesnesi
(DTO, data transfer object) kullanarak varlık çekirdeğinin durumunu taşımaktaydılar.
w.

Genel olarak DTO’lar olumlu görünmüyordu ve probleme kötü çözümler getiren karşıt
örüntüler (antipatterns) olarak adlandırılıyordu.

Diğer Yenilikler
ww

• Kurumsal çekirdeklerin EJB kabı dışında da test edilebilmesi desteği


• Nesne ilişkisel eşleme desteği
• Geliştirilmiş EJB QL
Kap Dışında Test Edilebilme
Daha önceki sürümlerdeki varlık çekirdeği bileşen modelinde üreteç ve bileşen
arayüzleri gereksinimleri, soyut (abstract) varlık çekirdekleri sınıfları ve sanal kalıcılık

m
alanları varlık çekirdeğinin kap dışında test edilmesi zorlaştırmaktaydı. Yeni
sürümdeki varlık çekirdeği modelinde bu arayüzlerle ilgili gereksinimler ortadan kalktı.
Varlık çekirdeği için gerekli olan tek şey somut kalıcılık alanlarına sahip, somut

o
çekirdek sınıfıdır. Buna ek olarak varlık çekirdeğinin yaşam döngüsü artık yaşam
döngüsü metotları kap tarafından gerçekleştirilen üreteç arayüzü ile değil

i.c
VarlıkYöneticisi API’sı ile denetlenecektir. Tüm bunlar varlık çekirdeklerini kaba daha
az bağımlı hale getirir ve kap dışında test edilmesini kolaylaştırır.
Önceden kaynaklanan kap dışında test edilme zorluğu kap tabanlı ilişkilerle
alakalıdır. Çünkü bu ilişkileri kap otomatik olarak yönetmekteydi. Çekirdek kap
dışında test edildiğinde kap içinde davranışı göstermiyor ve aynı sonuçları
dil
vermeyebiliyordu. Bunu engellemek ve kurumsal çekirdekler için kap dışında da test
edilebilme özelliğini destekleyebilmek için EJB 3.0 mimarisinde kap tabanlı
(container-managed) ilişkiler kaldırılmıştır ancak halen çekirdek tabanlı (bean-
managed) ilişkiler desteklenmektedir.
va
Nesne/İlişkisel Eşleme (Object/Relational Mapping)
EJB 3.0 belirtimleri nesne ilişkisel (O/R) eşleme için özel açıklama desteği
vermektedir. Bu destek ile ilişkisel veritabanı yapısı ile varlık çekirdekleri
ja

anahtarlanıyor bir başka deyişle O/R eşleme yöntemi ile nesne şeması ile veri tabanı
şeması eşleniyor. O/R eşleme belirtimi önceden EJB mimarisinin bir parçası değildi.
Bunun sağlanması ile geliştiricilere, veri model üzerinde, önceden olduğundan daha
w.

çok denetlenebilmesini sağlamaktadır.


EJB 3.0 mimarisinde, O/R eşleme kalıcılık ve çokbiçimlilik desteği vermektedir.
Bu, bir çekirdeğin diğerinin alt sınıfı olduğu sıradüzensel yapının ilişkisel veritabanı
yapısı ile eşleşmesini saplar. Başka sınıf ve alt sınıfların aynı sorguları ve metotları
ww

sıradüzensel yapıda, o sınıflara özel olarak kullanılabilmesi sağlar.


Özel açıklamalar tablo eşlemeleri, kolon eşlemeleri ve ilişkiler(birçoğa-bir ve bire-
birçok) için kullanılmaktadır.
Customer olarak adlandırılan varlık çekirdeğinin CUST olarak isimlendirilen
veritabanı tablosu ile eşleştirilmesi
@Entity
@Table(name="CUST")

public class Customer {...}

m
“Customer” varlık çekirdeği ile “Order” varlık çekirdeği arasındaki bire-birçok ilişki
gösterimi:

o
@Entity
@Table(name="CUST")

i.c
public class Customer {
private Set<Order>orders = new Hashset();
...

@OneToMany(cascade=ALL)
public Set<Order> getOrders() {

}
return orders; dil
public void setOrders(Set<Order> orders) {
va
this.orders = orders;
}
...

“cascade=ALL” belirtimi eylemlerin iliklilerle bağlanması anlamına gelmektedir.


ja

Böylece bir “Customer” nesnesi yaratıldığında ve verileri veritabanına kaydedildiğinde


tüm “orders” nitelikleri veritabanına kaydedilecektir.
Aşağıda kalıtımla eşleme örneği verilmektedir. “ValuedCustomer”, “Customer”
varlık çekirdeğinden türetilmiş bir varlık çekirdeğidir. Sıradüzensel yapı “CUST”
w.

tablosu ile eşleştirilmiştir.


ww

@Entity
@Table(name="CUST")
@Inheritance (strategy=SINGLE_TABLE,
discriminatorType=STRING,
discriminatorValue="CUST")
public class Customer {...}

@Entity

m
@Inheritance (discriminatorValue="VCUST")
public class ValuedCustomer extends Customer {...}
_______________________________________________________
@Entity

o
public class Customer {...}

@Entity

i.c
public class ValuedCustomer extends Customer {...}

Geliştirilmiş EJB QL

dil
EJB mimarisi içinde EJB QL çok kullanılmasına rağmen SQL sorgu dilinde
bulunan yığın günleme ve silme işlemleri, dış birleştirim (outer join) , izdüşüm
(projection) ve alt sorgu (subqueries) işlemleri gibi temel sorgular yönünden eksikti.
Ancak EJB 3.0 sürümü ile bu özellikler EJB QL’ye eklenmiştir.
va

Kaynaklar
http://java.sun.com/developer/technicalArticles/ebeans/ejbease/
ja

http://www.theserverside.com/articles/article.tss?l=SimplifyingEJB3
http://radio.weblogs.com/0135826/2004/09/29.html
http://www.sys-con.com/story/?storyid=46975&DE=1
http://www.javaworld.com/javaworld/jw-08-2004/jw-0809-ejb.html
w.

http://docs.jboss.org/ejb3/tutorial/
http://www.adtmag.com/article.asp?id=9476
http://www.caucho.com/resin-3.0/ejb3/tutorial/index.xtp
http://www.oracle.com/technology/tech/java/newsletter/articles/toplink/preparing_for_ej
b_3.html
ww

http://java.sun.com/products/ejb/docs.html (EJB 3.0 specification)

You might also like