EclipseLink – 06 – Hibernate JPA

Merhaba Arkadaslar.
Onceki bolumde nasil kolaylikla farkli veritabani yonetim sistemleri kullandigimizi inceledik. Bu yazida da benzer kolaylikta farkli JPA implementation’larini nasil kullanabilecegimizi inceleyecegiz.

Ilk yazida soz etmistik , Hibernate icin 2 farkli ORM urunu mevcuttur ; bir tanesi Native Hibernate bir tanesi ise JPA spect’ini uygulayan Hibernate urunudur.

JPA spec’tinde ornegin persist metodu kullanilmaktadir. Native Hibernate’de bu save metoduyla yapilmaktadir fakat diger Hibernate urunu JPA spec’tini uyguladigi icin yine persist metodu kullanilmaktadir.

Oncelikle Hibernate dependency projemize ekleyelim ; Hibernate ORM Downloads
Linke bakacak olursak 2 tane dependency tanimi gorebiliriz. Bizi ilgilendiren kisim

<!-- for JPA, use hibernate-entitymanager instead of hibernate-core -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>5.0.0.CR1</version>
</dependency>

Tabi ilerleyen zamanlarda versiyon degisecektir , siz en guncel versiyonu kullanabilirsiniz.

Guncelleme :
Eger 5.0.5Final versiyonu kullanacaksaniz dependency olarak jta da eklemek gerekli. Aksi durumda Exception alacaksinizdir ;

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-entitymanager</artifactId>
	<version>5.0.5.Final</version>
</dependency>


 <dependency>
	<groupId>javax.transaction</groupId>
	<artifactId>jta</artifactId>
	<version>1.1</version>
</dependency>

persistence.xml dosyamiza yeni bir Persistence Unit ekleyelim.

	<persistence-unit name="EmployeePersistenceUnitForHibernate"
		transaction-type="RESOURCE_LOCAL">
		
		<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
		
		<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" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="" />									
			<property name="hibernate.hbm2ddl.auto" value="create"/>
			<property name="hibernate.id.new_generator_mappings" value="true"/>					
		</properties>
		
	</persistence-unit>

Burada dikkat etmemiz gereken nokta <provider>  etiketidir. Bu etiketi EclipseLink reference implemantation’i kullanirken belirtmedik. Persistence Unit’in olusturulmasi icin javax.persistence.spi.PersistenceProvider arabirimini uygulayan sinif aranir. <provider> belirtilmediginde varsayilan olarak org.eclipse.persistence.jpa.PersistenceProvider sinifi yuklenecektir/loading.

Varsayilan olarak ;

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

Hem Eclipselink jari hem Hibernate jari oldugu durumda eger ozellikle belirtmezsek org.eclipse.persistence.jpa.PersistenceProvider kullanilir.
Bu nedenle burada ozellikle <provider> etiketimizi kullanmamiz gereklidir.

<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

Sonrasinda tablolarimizin otomatik olarak olusmasi icin EclipseLink’te oldugu gibi hibernate.hbm2ddl.auto property’sini kullanabiliriz.
EclipseLinkte bu property eclipselink.ddl-generation idi. Daha fazla Hibernate property icin
Chapter 3. Configuration

Veritabanina baglanmak icin kullandigimiz javax.persistence.jdbc.driver gibi property bilgilerini Hibernate icin de kullanabiliriz. Bununla birlikte dilersek Hibernate Datasource Properties’lerini kullanabiliriz.

		
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa.schema" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="" />	

Bir diger property olarak hibernate.id.new_generator_mappings kullandik.MySQL icin GenerationType.SEQUENCE problem cikarmaktadir.
org.hibernate.MappingException: org.hibernate.dialect.MySQL5Dialect does not support sequences seklinde bir hata verecektir. Bu hataya engel olmak icin ilgili property degerini kullanmamiz gereklidir.

Chapter 3. Configuration  hibernate.id.new_generator_mappings ile ilgili notu inceleyecek olursak , JPA ile uyumluluk ve verimlilik icin kullanilmasi onerilmektedir.

We recommend all new projects which make use of to use @GeneratedValue to also set hibernate.id.new_generator_mappings=true as the new generators are more efficient and closer to the JPA 2 specification semantic. However they are not backward compatible with existing databases (if a sequence or a table is used for id generation).

Burada dikkate edecek olursak <class> etiketini kullanmadik. Hibernate icin bu durum problem teskil etmemektedir.

Simdi de onceki bolumde yaptigimiz ornekleri tanimladigimiz bu Persistence Unit i kullanacak sekilde calistiralim ve sonuclari gorelim.

NOT:
@GeneratedValue(strategy=GenerationType.IDENTITY) Oracle icin problem cikartmaktadir. Bu annotation oldugunda Hibernate icin AUTO , TABLE , SEQUENCE testlerimiz gerceklesmeyecektir. Bu nedenle bu testleri yapmadan once Employee13.java sinifimizda annotation’i degisitirip/kaldirip test yapalim.

org.hibernate.dialect.Oracle10gDialect does not support identity key generation

AUTO

Employee10.java

package _10.idgeneration.auto.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Employee10 {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	private String name;
	private String surname;
	private int salary;

	//constructors
	//getter setter
	//toString

}

EmployeeTest.java

package _10.idgeneration.auto.test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import _10.idgeneration.auto.model.Employee10;
import _10.idgeneration.auto.service.EmployeeService;
import _10.idgeneration.auto.service.EmployeeServiceImpl;

public class EmployeeTest {

	public static void main(String[] args) {
	    		    	
		//EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("EmployeePersistenceUnit");
		EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("EmployeePersistenceUnitForHibernate");
		//Hibernate icin Persistence Unit
		
		....

	}
}

hibernate mysql generationtype auto

MySQL icin hibernate_sequence adinda bir tablo olusur ve sadece next_val adinda bir column a sahiptir.

Oracle icin test ettigimizde HIBERNATE_SEQUENCE adinda bir Sequence objesi olusur.

TABLE

MySQL ve Oracle icin HIBERNATE_SEQUENCES (sonunda S var) tablo olusur.

Employee11.java

	@Entity
	public class Employee11 {
		@Id
		@GeneratedValue(strategy = GenerationType.TABLE)
		private int id;
		..

	}

EmployeeTest.java

package _11.idgeneration.table.test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import _11.idgeneration.table.model.Employee11;
import _11.idgeneration.table.service.EmployeeService;
import _11.idgeneration.table.service.EmployeeServiceImpl;

public class EmployeeTest {

    public static void main(String[] args) {
	//EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("EmployeePersistenceUnit");
	EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("EmployeePersistenceUnitForHibernate");
	EntityManager entityManager = entityManagerFactory.createEntityManager();
	EntityTransaction entityTransaction = entityManager.getTransaction();

	...
    }
}

hibernate oracle table hibernate sequences

@TableGenerator kullanimini da kendiniz inceleyebilirsiniz.

SEQUENCE

Employee12.java

package _12.idgeneration.sequence.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;

@Entity
public class Employee12 {

//	@Id
//	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	
	@SequenceGenerator(name="Emp_Gen", sequenceName="EMP_SEQUENCE", initialValue=20, allocationSize=30)
	@Id @GeneratedValue(generator="Emp_Gen" , strategy= GenerationType.SEQUENCE)
	private int id;
	private String name;
	private String surname;
	private int salary;

	//getter setter
	//constructor
	//toString
}

EmployeeTest.java

package _12.idgeneration.sequence.test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import _12.idgeneration.sequence.model.Employee12;
import _12.idgeneration.sequence.service.EmployeeService;
import _12.idgeneration.sequence.service.EmployeeServiceImpl;

public class EmployeeTest {

    public static void main(String[] args) {
	//EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("EmployeePersistenceUnit");
	EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("EmployeePersistenceUnitForHibernate");
	EntityManager entityManager = entityManagerFactory.createEntityManager();
	EntityTransaction entityTransaction = entityManager.getTransaction();

	...

    }
}

Oracle icin test ettigimizde EMP_SEQUENCE , sequence objemiz olusur. MySQL de EMP_SEQUENCE tablomuz olusur.

hibernate sequencegenerator oracle

persistence.xml
persistence.xml dosyamizin icerigi ;

<?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>
		<class>_02.field.access.model.Employee2</class>
		<class>_03.property.access.model.Employee3</class>
		<class>_04.mixed.access.model.Employee4</class>
		<class>_05.mapping.table.model.Employee5</class>
		<class>_06.mapping.column.model.Employee6</class>
		<class>_07.mapping.enumerated.model.Employee7</class>
		<class>_08.mapping.temporal.model.Employee8</class>
		<class>_09.mapping.lob.model.Employee9</class>
		<class>_10.idgeneration.auto.model.Employee10</class>
		<class>_11.idgeneration.table.model.Employee11</class>
		<class>_12.idgeneration.sequence.model.Employee12</class>
		<class>_13.idgeneration.identity.model.Employee13</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" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="" />
			
			<!-- 				
			<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1520:xe" />
			<property name="javax.persistence.jdbc.user" value="Levent" />
			<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-unit name="EmployeePersistenceUnitForHibernate"
		transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
		<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" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="" />											
		 -->
		 
		 <!-- javax.persistence.jdbc... property'lerini Hibernate icin de problemsiz sekilde kulanabiliriz. -->
		 
		
			<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
			<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa.schema" />
			<property name="hibernate.connection.username" value="root" />
			<property name="hibernate.connection.password" value="" />
		
		
			<!-- 
			<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver" />
			<property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1520:xe" />
			<property name="hibernate.connection.username" value="Levent" />
			<property name="hibernate.connection.password" value="123456" />
			-->
			
			<property name="hibernate.hbm2ddl.auto" value="create"/>
			<property name="hibernate.id.new_generator_mappings" value="true"/>	
		</properties>
		
	</persistence-unit>
</persistence>

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

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *