Table of Contents
Spring data JPA provides jpaTemplate to integrate Spring and JPA.
Why Spring data JPA:
It is quite cumbersome to implement data access layer now a day. You need to write too much boiler plate code to even execute simple queries and you have to write too much code before and after executing queries. Spring data JPA provides APIs which is quite abstract and you just need to write repository interface  and Spring data JPA will provide implementation automatically. You can also declare some custom find methods (findCountryByName) and spring will provide implementation for it.
Download source code:
Lets understand more with the help of example:
Create Country table in mysql database with following code:
1 2 3 4 5 6 7 8 9 |
CREATE TABLE COUNTRY ( id int PRIMARY KEY NOT NULL AUTO_INCREMENT, countryName varchar(100) NOT NULL, population int NOT NULL ) ; |
Step 1:
Create a simple maven java project as “SpringDataJPAHibernateExample”.
Step 2:
Include Spring data, hibernate and mysql dependency in pom.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.arpit.java2blog</groupId> <artifactId>SpringDataJPAHibernateExample</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringDataJPAHibernateExample</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.2.1.RELEASE</spring.version> <hibernate.version>4.3.5.Final</hibernate.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.8.0.RELEASE</version> </dependency> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.1-api</artifactId> <version>1.0.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> </dependencies> </project> |
Step 3:Lets create our bean class Country.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
package org.arpit.java2blog.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; /* * This is our model class and it corresponds to Country table in database */ @Entity @Table(name="COUNTRY") public class Country{ @Id @Column(name="id") @GeneratedValue(strategy=GenerationType.IDENTITY) int id; @Column(name="countryName") String countryName; @Column(name="population") long population; public Country() { super(); } public Country(int i, String countryName,long population) { super(); this.id = i; this.countryName = countryName; this.population=population; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCountryName() { return countryName; } public void setCountryName(String countryName) { this.countryName = countryName; } public long getPopulation() { return population; } public void setPopulation(long population) { this.population = population; } @Override public String toString() { return "Country [id=" + id + ", countryName=" + countryName + ", population=" + population + "]"; } } |
Create a repository interface named CountryRepository.java
You don’t need to provide implementation of it, Spring JPA will provide it automatically.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package org.arpit.java2blog.jpa; import java.util.List; import org.arpit.java2blog.model.Country; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; public interface CountryRepository extends CrudRepository<Country,Integer> { Country findCountryByCountryName(String name); @Query("select country from Country country where country.population >= ?1 and country.population <= ?2") List findCountriesPopulationRange(long from, long to); } |
Create applicationcontext.xml as below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<?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:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <jpa:repositories base-package="org.arpit.java2blog.jpa" /> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="org.arpit.java2blog" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="generateDdl" value="true" /> </bean> </property> </bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/CountryData" /> <property name="username" value="root" /> <property name="password" value="arpit123" /> </bean> <bean id="mainClass" class="org.arpit.java2blog.main.SpringApplicationMainBean"> </bean> </beans> |
entityManagerFactory will have reference to dataSource and jpaVendorAdapter.
Step 6:
Create Main class named SpringApplicationMainBean.java as below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
package org.arpit.java2blog.main; import java.util.List; import javax.sql.DataSource; import org.arpit.java2blog.jpa.CountryRepository; import org.arpit.java2blog.model.Country; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringApplicationMainBean { @Autowired private CountryRepository repository; public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); SpringApplicationMainBean samb= (SpringApplicationMainBean) context.getBean("mainClass"); samb.addCountries(); System.out.println("====================================="); // Read Country countryRead = samb.getCountry(3); System.out.println("Getting country with ID 3::" + countryRead.getCountryName()); System.out.println("====================================="); System.out.println("Getting all Countries"); // Get All Iterable countryList = samb.getAllCountries(); countryList.forEach(c -> System.out.println(c)); System.out.println("====================================="); System.out.println("Finding countryName Bhutan"); // find country by name Country country =samb.findCountryByName("Bhutan"); System.out.println(country); System.out.println("====================================="); System.out.println("Finding All Countries which have population from 2000 to 20000"); // find countries by population ranges List countries=samb.findCountryByPopulationRange(2000,20000); System.out.println(countries); System.out.println("====================================="); System.out.println("We are done with all operations"); } public void addCountries() { // Add Country object to database Country countryUSA = new Country(); countryUSA.setCountryName("USA"); countryUSA.setPopulation(10000); Country countryIndia = new Country(); countryIndia.setCountryName("India"); countryIndia.setPopulation(20000); Country countryChina = new Country(); countryChina.setCountryName("China"); countryChina.setPopulation(30000); Country countryBhutan = new Country(); countryBhutan.setCountryName("Bhutan"); countryBhutan.setPopulation(5000); // Add Country repository.save(countryUSA); repository.save(countryIndia); repository.save(countryChina); repository.save(countryBhutan); } public Country getCountry(int id) { return repository.findOne(id); } public Iterable getAllCountries() { return repository.findAll(); } public Country findCountryByName(String countryName) { return repository.findCountryByCountryName(countryName); } public List findCountryByPopulationRange(long populationTo,long populationFrom) { return repository.findCountriesPopulationRange(populationTo,populationFrom); } } |
When you run above program, you will get below output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. Sep 13, 2016 12:36:15 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation INFO: HHH000204: Processing PersistenceUnitInfo [ name: default ...] Sep 13, 2016 12:36:16 PM org.hibernate.Version logVersion INFO: HHH000412: Hibernate Core {4.3.5.Final} Sep 13, 2016 12:36:16 PM org.hibernate.cfg.Environment INFO: HHH000206: hibernate.properties not found Sep 13, 2016 12:36:16 PM org.hibernate.cfg.Environment buildBytecodeProvider INFO: HHH000021: Bytecode provider name : javassist Sep 13, 2016 12:36:16 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final} Sep 13, 2016 12:36:17 PM org.hibernate.dialect.Dialect INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect Sep 13, 2016 12:36:17 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4 Sep 13, 2016 12:36:17 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory INFO: HHH000397: Using ASTQueryTranslatorFactory Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000228: Running hbm2ddl schema update Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000102: Fetching database metadata Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000396: Updating schema Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.TableMetadata INFO: HHH000261: Table found: CountryData.country Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.TableMetadata INFO: HHH000037: Columns: [countryname, id, population] Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.TableMetadata INFO: HHH000108: Foreign keys: [] Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.TableMetadata INFO: HHH000126: Indexes: [primary] Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000232: Schema update complete ===================================== Getting country with ID 3::China ===================================== Getting all Countries Country [id=1, countryName=USA, population=10000] Country [id=2, countryName=India, population=20000] Country [id=3, countryName=China, population=30000] Country [id=4, countryName=Bhutan, population=5000] ===================================== Finding countryName Bhutan Country [id=4, countryName=Bhutan, population=5000] ===================================== Finding All Countries which have population from 2000 to 20000 [Country [id=1, countryName=USA, population=10000], Country [id=2, countryName=India, population=20000], Country [id=4, countryName=Bhutan, population=5000]] ===================================== We are done with all operations |
Awesome example! I would like to mention that there is a need to add the property for the database dialect.