Spring – 22 – JPA – 02

Merhaba Arkadaslar
Onceki bolumde Spring ve JPA entegrasyonunu LocalEntityManagerFactoryBean sinifini kullanarak gerceklestirdik. Bu bolumde LocalContainerEntityManagerFactoryBean sinifini kullanarak Spring ve JPA entegrasyonunu gerceklestirecegiz.

Onceki ornegimizdeki siniflari aynen burada kullanacagiz. Burada bizim icin onemli olan nokta XML dosyamizdaki konfigurasyon olacak.

Person.java

package _28.jpa.model;

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

@Entity
public class Person {

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

	public Person() {
		super();
	}

	public Person(String name, String surname, int salary) {
		super();
		this.name = name;
		this.surname = surname;
		this.salary = salary;
	}

	//getters and setters
	...
}

persistence.xml
Ilgili sinifi tanimlayalim , diger Person sinifini disable edelim.

....

<!-- 
<class>_27.jpa.model.Person</class>
 -->

<class>_28.jpa.model.Person</class>
....

PersonDAO.java

package _28.jpa.dao;

import java.util.List;
import _28.jpa.model.Person;

public interface PersonDAO {

	public void insert(Person person);

	public Person getPersonById(int id);

	public List<Person> getAllPersons();

	public void update(Person person);

	public void delete(int id);

}

28.jpa.xml
XML dosyamizi inceleyecek olursak ;

    • Oncelikle PropertyPlaceholderConfigurer sinifi icin bean tanimini gerceklestiriyoruz.
    • jdbc.properties dosyasini kullanarak DriverManagerDataSource datasource sinifimiz icin bean tanimini gerceklestiriyoruz. Bu 2 adimi JDBC orneklerimizde gerceklestirmistik.
    • LocalContainerEntityManagerFactoryBean icin bean tanimini gerceklestiriyoruz. Bu sinifta LocalEntityManagerFactoryBean de olmayan property’ler mevcuttur.
      Ornegin LocalEntityManagerFactoryBean sinifi icin dataSource tanimi olmadigi icin mutlaka JDBC tanimi persistence.xml dosyasinda olmak zorundadir. Fakat burada JDBC tanimlari icin DriverManagerDataSource sinifini ve jdbc.properties dosyasini kullandik. Bu sayede persistence.xml dosyasindan JDBC konfigurasyonunu silsek de herhangi bir problemle karsilasmayiz.
    • JPA implemantation olarak EclipseLink kullandigimizda ,@Entity annotation’ini kullandigimiz siniflar icin persistence.xml dosyasinda mutlaka <class> tanimini yapmamiz gereklidir.Fakat LocalContainerEntityManagerFactoryBean kullandigimizda packagesToScan property sayesinde ilgili @Entity siniflarinin yer aldigi package bilgisini vermemiz yeterli olacaktir.Boylece otomatik olarak @Entity siniflari  bulunacaktir.
    • persistence.xml dosyasi varsayilan olarak source folder/META-INF altinda yer almalidir.
      persistenceXmlLocation property’sini kullanarak persistence.xml dosyasinin bulunacagi dizini degistirebiliriz.
    • persistence.xml dosyasinda kullandigimiz cesitli konfigurasyonlari LocalContainerEntityManagerFactoryBean bean taniminda gerceklestirebiliriz. Bunun icin jpaProperties property’sini kullanabiliriz. Burada tanimladigimiz konfigurasyonlar persistence.xml dosyasindaki konfigurasyonlari override edecektir. Ornegin log level olarak FINE tanimladik , persistence.xml dosyasinda bu deger OFF , dolayisiyla burada tanimladigimiz deger kullanilacaktir.
    • Bir diger property olarak jpaVendorAdapter ‘u kullanmamiz gerekmektedir. Burada PersistenceProvider olusturacak Adapter sinif bilgisini vermemiz gereklidir.
      EclipseLink kullandigimiz icin EclipseLinkJpaVendorAdapter sinifini kullaniyoruz. EclipseLinkJpaVendorAdapter sinifini incelersek JPA icin default PersistenceProvider olan org.eclipse.persistence.jpa.PersistenceProvider objesi kullanildigini gorebiliriz.
public class EclipseLinkJpaVendorAdapter extends AbstractJpaVendorAdapter {

	private final PersistenceProvider persistenceProvider = new org.eclipse.persistence.jpa.PersistenceProvider();

	private final EclipseLinkJpaDialect jpaDialect = new EclipseLinkJpaDialect();

..
}
  • Son olarak jpaPropertyMap property’sini kullaniyoruz. Burada eclipselink.weaving key i icin false degeri vermemiz gerekli. Aksi durumda su hatayi aliriz ;
    Caused by: java.lang.IllegalStateException: Cannot apply class transformer without LoadTimeWeaver specifiedEclipseLink varsayilan olarak calisma zamaninda/runtime weaving in aktif olmasini beklemektedir. Bu konuda daha fazla bilgi icin ;
    stackoverflow.com
  • Daha sonrasinda @Autowired isleminin gerceklesmesi icin contex:component-scan tag’ini kullaniyoruz. context ve spring-context.xsd eklememiz gereklidir.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context.xsd">

	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location">
			<value>jdbc/jdbc.properties</value>
		</property>
	</bean>

	<bean id="dataSourceId"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>


	<bean id="entityManagerFactoryId"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

		<property name="dataSource" ref="dataSourceId" />
		<property name="jpaVendorAdapter">
			<bean
				class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" />
		</property>
		<property name="packagesToScan" value="_28.jpa.model" />
		<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
		<property name="jpaProperties">
			<props>
				<prop key="eclipselink.ddl-generation">drop-and-create-tables</prop>
				<prop key="eclipselink.logging.level">FINE</prop>
			</props>
		</property>

		<property name="jpaPropertyMap">
			<map>
				<entry key="eclipselink.weaving" value="false" />
			</map>
		</property>
	</bean>


	<!-- @Autowired annotation kullaniyoruz. -->
	<context:component-scan
		base-package="_28.jpa.dao"/>

	<!-- 
	<bean id="personDAOImpl" class="_28.jpa.dao.PersonDAOImpl">
		<property name="entityManagerFactory" ref="entityManagerFactoryId" />
	</bean>
	 -->

</beans>

PersonDAOImpl.java

@Repository("personDAOImpl")
public class PersonDAOImpl implements PersonDAO {

	private EntityManager entityManager;

	@Autowired
	public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
		entityManager = entityManagerFactory.createEntityManager();
	}
        ...
        //implementation
}

JPATest.java

package _28.jpa.test;

import java.sql.SQLException;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import _28.jpa.dao.PersonDAO;
import _28.jpa.dao.PersonDAOImpl;
import _28.jpa.model.Person;


public class JPATest {
	public static void main(String[] args) throws SQLException {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("28.jpa.xml");


		PersonDAO pService = ctx.getBean(PersonDAOImpl.class);

		// create person object
		Person person1 = new Person("oldName", "oldSurname", 1989);

		// insert
		pService.insert(person1);

		// find
		Person foundPerson = pService.getPersonById(1);
		System.out.println("Found ... " + foundPerson);

		// update
		person1.setName("Levent");
		person1.setSurname("Erguder");
		pService.update(person1);
		System.out.println("After Update...");

		// find
		foundPerson = pService.getPersonById(1);
		System.out.println("Found ... " + foundPerson);

		Person person2 = new Person("James", "Gosling", 1955);
		Person person3 = new Person("Joshua", "Bloch", 1961);

		pService.insert(person2);
		pService.insert(person3);

		// delete
		pService.delete(1);

		// list
		List<Person> personList = pService.getAllPersons();
		System.out.println("Listing...");
		for (Person p : personList) {
			System.out.println(p);
		}

		((ClassPathXmlApplicationContext) ctx).close();
	}
}

Github kaynak dosyalar/ source folder
leventerguder/injavawetrust-spring-tutorial

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 *