EclipseLink – 02 – Hello EclipseLink
Merhaba Arkadaslar
Bu bolumde Entity Metadata kavramini ve EclipseLink gozunden Entity ozelliklerini inceleyecegiz. Java Persistence API icin onemli olan kavramlari inceleyecegiz. Sonrasinda Persistence Unit konfigurasyon dosyasini inceleyecegiz. Son olarak ornek bir uygulama yapacagiz.
Entity Metadata
Metadata/ustveri , bir nesne ya da olguyu herhangi bir sekilde tanimlayan veri gibi bir anlama gelmektedir.
Entity Metadata ; Entity’leri tanimlamak icin kullanmamiz/belirtmemiz gereken bilgi olarak ifade edebiliriz. Bunun icin diger Java teknolojilerinde oldugu gibi 2 yontem kullanilir.
- Annotations (bilgi notu)
- XML
Annotations
Annotation metadata ozelligi , Java SE 5 ile gelen , Source code / kaynak koda eklenen bir ifadedir.
XML
Geleneksel olarak metadata olarak XML kullanilmaktadir. XML ya da annotation kullanmak tercihe ve projeye baglidir. Orneklerimizi annotation ile yapacagiz , ilerleyen bolumlerde de XML ile Entity tanimlarini inceleyecegiz.
Entity , JPA Specification
- Entity class’larda mutlaka no-arg constructor tanimli olmalidir. Bununla birlikte baska yapilandiricilar da tanimli olabilir.
- JPA Spect’ine gore bu no-arg constructor’lar public ya da protected olmalidir. EclipseLink bu kurali uygulamiyor , bununla birlikte Eclipste JPA validation acik olursa bu durumda private no-arg constructor tanimlamamiza izin vermez , derleme hatasi verir. Bu validation icin oncelikle Maven Update yapmamiz gereklidir.
- Entity class’lari top-level class olmalidir , nested class’lar Entity olamaz. Bununla birlikte interface ya da enum’lar da Entity olamaz.
- JPA Spect’ine gore Entity class’lar , instance variable’lar final olamaz. Bu durumda Eclipse , JPA Validator aktif ise compile error/derleme hatasi verecektir fakat JPA Validator aktif degilse calisma zamaninda/runtime herhangi bir problem olmaz.
- Entity’ler inheritance ve polymorphism’i destekler.
- Abstract ve non-abstract/concrete class’lar Entity olabilir.
Create Project
EclipseLink ile calisabilmek icin Java SE projesi yeterli olacaktir. Projemiz Maven tabanli olacak, bunun icin Maven projesi olusturabilir ya da Java projesi icin Configure –> Convert To Maven Project secenegini kullanabilirsiniz.
pom.xml dosyamiza gerekli jarlarimizin dependency tanimlarini ekleyelim.
pom.xml
Projemiz icin gerekli olan JPA jari ve EclipseLink implemantation jarini ekleyelim. Veritabani olarak bu ornegimizde MySQL kullanacagiz.
<properties> <eclipselink.version>2.6.4</eclipselink.version> <mysql.version>6.0.4</mysql.version> </properties> <dependencies> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>${eclipselink.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> </dependencies>
Maven ilgili dependency’leri de indirecektir.
Java Persistence API World
JPA orneklerinde kullanacagimiz temel kavramlar vardir. Bu temel kavramlara ornek olarak ;
public interface EntityManagerFactory public interface EntityManager public interface EntityTransaction public interface Query public class Persistence public @interface PersistenceContext public @interface PersistenceUnit
Persistence , EntityManagerFactory elde etmek icin kullanilir. 1 Persistence N tane EntityManagerFactory olusturabilir.
Persistence sinifi , EntityManagerFactory olusturabilmesi icin PersistenceUnit bilgisini kullanir.
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("PersistenceUnitName");
EntityManagerFactory , EntityManager elde etmekten/olusturmaktan sorumludur.
1 EntityManagerFactory N tane EntityManager olusturabilir.
1 EntityManagerFactory , 1 PersistenceUnit tarafindan konfigure edilir.
EntityManager entityManager = entityManagerFactory.createEntityManager();
PersistenceUnit , entity class’larin belirtildigi/deklare edildigi ve veritabani bilgilerinin yer aldigi konfigurasyon bilgisidir.
EntityManager objesi Entity uzerinde yapilan tum islemlerden sorumludur.
EntityManager tarafindan yonetilen/managed tum Entity objeler kumesine/tumune PersistenceContext denilir.
Persistence Unit
Persistence Unit , entity class’larin belirtildigi/deklare edildigi ve veritabani bilgilerinin yer aldigi konfigurasyon bilgisidir.
Bu konfigurasyonu persistence.xml dosyasinda tanimlayabiliriz. persistence.xml dosyasi META-INF klasoru altinda yer almalidir.
persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1"> <persistence-unit name="EmployeePersistenceUnit" transaction-type="RESOURCE_LOCAL"> <class>_01.hello.eclipselink.model.Employee</class> <properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa.schema?serverTimezone=UTC" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="123456" /> <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> <property name="eclipselink.logging.level" value="OFF"/> </properties> </persistence-unit> </persistence>
<persistence-unit> etiketi/tagi ile Persistence Unit tanimlayabiliriz. <persistence-unit> etiketi 2 tane attribute/ozellik alir name ve transaction-type.
name attribute’u zorunludur , transaction-type ise secimliktir varsayilan olarak RESOURCE_LOCAL degerine sahiptir. Bununla birlikte JTA (Java Transaction API) degerine de sahip olabilir. Simdilik Java SE ortamiyla calisacagimiz icin RESOURCE_LOCAL transaction-type bizim icin yeterli olacaktir.
Transaction kavramini onceki yazida incelemistik. Transaction hizmeti/service javax.persistence.EntityTransaction arabiriminde yer alan begin , commit , rollback gibi metotlarla saglanacaktir.
<class> etiketi/tagi ile Entity siniflarimizi packagename.classname seklinde belirtiyoruz. Bu islem zorunludur.
Daha sonrasinda veritabanina baglanmak icin gerekli bilgileri <properties> etiketi icerisine ekliyoruz. Bunun icin <property> etiketini kullaniyoruz.
javax.persistence.jdbc.driver , javax.persistence.jdbc.url gibi <property> leri kullanarak veritabani baglantisi saglanmasi icin gerekli olan driver url username password bilgilerini tanimliyoruz. Bu ornegimizde MySQL kullaniyoruz , siz de kendinize uygun olacak sekilde bu anlnlari guncelleyebilirsiniz.
Daha sonrasinda elipselink.ddl-generation <property> sini kullanarak otomatik olarak tablomuzun olusmasini saglayabiliriz. elipselink.ddl-generation su degerlerine sahip olabilir.
- drop-tables – DROP_ONLY
- create-tables – CREATE_ONLY
- drop-and-create-tables – DROP_AND_CREATE
- create-or-extend-tables – CREATE_OR_EXTEND
- none – NONE (DEFAULT)
Daha fazla <property> icin suraya bakabilirsiniz ;
EclipseLink 2.6.0, API Reference
Son olarak Eclipselink icin Log seviyesini ayarliyoruz. Console da loglar basilmasin istiyorsak bu durumda OFF secenegi isimizi gorecektir. Daha fazla secenek icin ;
EclipseLink/Examples/JPA/Logging
Creating an Entity
Onceki bolumlerde Entity kavramini ve Entity’in ozelliklerini inceledik. POJO (Plain Old Java Object) siniflarimiza ekleyecegimiz annotation’larla Entity bean ozeligine sahip olabilirler.
En temel kullanacagimiz annotation’lar @Entity ve @Id annotation’laridir. Bunlar bir Entity tanimlamak icin gerekli olan minimum metadata’dir.
@Entity annotation’i sinifimizin basina yaziyoruz. Her Entity’in mutlaka id degeri olmalidir bu nedenle @Id annotation zorunludur. @Id annotation’i da primary key olarak kullanacagimiz instance variable’in uzerine yaziyoruz.
Employee.java
package _01.hello.eclipselink.model; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Employee { @Id private int id; private String name; private String surname; private int salary; public Employee() { super(); } public Employee(int id, String name, String surname, int salary) { super(); this.id = id; this.name = name; this.surname = surname; this.salary = salary; } //getters and setters //toString }
DAO/Data Access Object Layer
Simdi de Employee Entity’leri icin kullanacagimiz EmployeeDAO metotlarini yazalim.
EmployeeDAO.java
package _01.hello.eclipselink.dao; import java.util.List; import _01.hello.eclipselink.model.Employee; public interface EmployeeDAO { public Employee insertEmployee(int id, String name, String surname, int salary); public Employee findEmployee(int id); public List<Employee> findAllEmployees(); public void removeEmployee(int id); public Employee raiseEmployeeSalary(int id, int raise); }
EmployeeDAOImpl.java
insertEmployee metodumuzda entityManager reference degiskeni uzerinden persist metodunu kullaniyoruz.
persist metodu ile Entity objemizi veritabanina kaydederiz. Bunun icin kullanilan baska metotlar da mevcuttur. Ilerleyen bolumlerde inceleyecegiz.
findEmployee metodumuzda entityManager reference degiskeni uzerinden find metodunu kullaniyoruz.
class ve id bilgisi vererek veritabanina ekledigimiz Entity objemizi veritabanindan getiririz.
findAllEmployees metodunda entityManager reference degiskeni uzerinden createQuery metodunu kullaniyoruz.
Burada basit bir query yazdik. Ilerleyen bolumlerde query konusunu inceleyecegiz. Dikkat edecek olursak temel olarak SQL sorgusuna benzer sekildedir.
removeEmployee metodunda entityManager reference degiskeni uzerinden remove metodunu kullaniyoruz.
remove metoduna Entity objemizi arguman olarak veriyoruz ve ilgili Entity objemiz veritabanindan silinir.
raiseEmployeeSalary metodunda setSalary metodunu kullaniyoruz. Entity objemiz uzerinden setter metodu bir transactionda cagirdigimizda yaptigimiz bu guncelleme veritabanina da yansitilir.
package _01.hello.eclipselink.dao; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.Query; import _01.hello.eclipselink.model.Employee; public class EmployeeDAOImpl implements EmployeeDAO { private EntityManager entityManager; public EmployeeDAOImpl(EntityManager entityManager) { this.entityManager = entityManager; } @Override public Employee insertEmployee(int id, String name, String surname, int salary) { Employee employee = new Employee(id, name, surname, salary); entityManager.persist(employee); return employee; } @Override public Employee findEmployee(int id) { return entityManager.find(Employee.class, id); } @SuppressWarnings("unchecked") @Override public List<Employee> findAllEmployees() { Query query = entityManager.createQuery("Select e from Employee e"); return query.getResultList(); } @Override public void removeEmployee(int id) { Employee employee = findEmployee(id); if (employee != null) { entityManager.remove(employee); } } @Override public Employee raiseEmployeeSalary(int id, int raise) { Employee employee = findEmployee(id); if (employee != null) { employee.setSalary(employee.getSalary() + raise); } return employee; } }
- findEmployee metoduna id bilgisini arguman olarak veriyoruz geriye Employee objemiz donuyor. entityManager.find metodu icin bir transaction’a gerek yoktur.
- raiseEmployeeSalary metounda guncelleme islemi yapiyoruz. employee.setSalary metodunu bir transaction icerisinde cagirdigimiz icin guncelleme islemi veritabanina yansitilacaktir.
- Daha sonrasinda removeEmployee metodunda entityManager.remove metodu calisir ve veritabanindan silme islemi gerceklesir.
- Son olarak findAllEmployees metodunda entityManager.createQuery metodu calisir ve geriye List <Employee> donecektir.
Test
EmployeeTest.java
- Oncelikle Persistence sinifini kullanarak createEntityManagerFactory metoduna PersistenceUnit bilgisini arguman olarak veririz. Boylelikle PersistenceUnit’ten EntityManagerFactory objesi elde ederiz.
- Daha sonrasinda entityManagerFactory uzerinden createEntityManager metodu yardimi ile EntityManager objesine sahip oluruz.
- entityManager uzerinden getTransaction metodu EntityTransaction objesine sahip oluruz.
- Burada dikkat edecek olursak insertEmployee , raiseSalary ve deleteEmployee metotlarini bir transaction icerisinde yapmamiz gereklidir.
package _01.hello.eclipselink.test; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import _01.hello.eclipselink.dao.EmployeeDAO; import _01.hello.eclipselink.dao.EmployeeDAOImpl; import _01.hello.eclipselink.model.Employee; public class EmployeeTest { public static void main(String[] args) { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("EmployeePersistenceUnit"); EntityManager entityManager = entityManagerFactory.createEntityManager(); EntityTransaction entityTransaction = entityManager.getTransaction(); EmployeeDAO employeeService = new EmployeeDAOImpl(entityManager); entityTransaction.begin(); Employee employee = employeeService.insertEmployee(1, "Levent", "Erguder", 1000); Employee employee2 = employeeService.insertEmployee(2, "James", "Gosling", 10000); Employee employee3 = employeeService.insertEmployee(3, "Joshua", "Bloch", 10000); entityTransaction.commit(); System.out.println("Persisted :" + employee); System.out.println("Persisted :" + employee2); System.out.println("Persisted :" + employee3); Employee employee4 = employeeService.findEmployee(1); System.out.println("Found : " + employee4); entityTransaction.begin(); Employee employee5 = employeeService.raiseEmployeeSalary(1, 1000); entityTransaction.commit(); System.out.println("Updated : " + employee5); entityTransaction.begin(); employeeService.removeEmployee(1); entityTransaction.commit(); System.out.println("findAllEmployees"); List<Employee> employees = employeeService.findAllEmployees(); for (Employee emp : employees) { System.out.println("Found : " + emp); } } }
Project Explorer
Project Explorer’a bakacak olursak Projemiz Maven tabanlidir.
persistence.xml dosyamiz META-INF dizini altinda olmalidir.
JPA Content kisminin cikmasi icin projenize sag tiklayip Maven -> Update Project yapilmalidir. Basta bahsettigim Validation konusu icin JPA Content olmalidir. Eclipse bu sekilde JPA validation taniyabilir. Kendiniz derleme hatasi veren durumlari test edebilirsiniz.
Run Application
Ornegimizi calistirdigimizda ;
Eclipse Console
Persisted :Employee [id=1, name=Levent, surname=Erguder, salary=1000] Persisted :Employee [id=2, name=James, surname=Gosling, salary=10000] Persisted :Employee [id=3, name=Joshua, surname=Bloch, salary=10000] Found : Employee [id=1, name=Levent, surname=Erguder, salary=1000] Updated : Employee [id=1, name=Levent, surname=Erguder, salary=2000] Removed Employee id:1 findAllEmployees Found : Employee [id=2, name=James, surname=Gosling, salary=10000] Found : Employee [id=3, name=Joshua, surname=Bloch, salary=10000]
MySQL Workbench
Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer
Leave a Reply