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
Leave a Reply