Spring Data JPA example

In this post, we are going to see about Spring data JPA.
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:
CREATE TABLE COUNTRY
(
   id int PRIMARY KEY NOT NULL AUTO_INCREMENT,
   countryName varchar(100) NOT NULL,
   population int NOT NULL
)
;
We will you use Country table for querying and updating values in database.
Step 1:
Create a simple maven java project as "SpringDataJPAHibernateExample".
Step 2:
Include Spring data, hibernate and mysql dependency in pom.xml.
<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
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 + "]";
 }
}
Step 4:
Create a repository interface named CountryRepository.java
You don't need to provide implementation of it, Spring JPA will provide it automatically.
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<Country> findCountriesPopulationRange(long from, long to); 
}
Step 5:
Create applicationcontext.xml as below
<?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>
Configure datasource based on your connections details.
entityManagerFactory will have reference to dataSource and jpaVendorAdapter.
Step 6:
Create Main class named SpringApplicationMainBean.java as below
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<Country> 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<Country> 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<Country> getAllCountries()
 {
  return repository.findAll();
 }
 
 public Country findCountryByName(String countryName)
 {
  return repository.findCountryByCountryName(countryName);
 }
 
 public List<Country> findCountryByPopulationRange(long populationTo,long populationFrom)
 {
  return repository.findCountriesPopulationRange(populationTo,populationFrom);
 }
}

As you can see, we have used autowire annotation to inject CountryRepository in above class. Spring automatically provides implementation for some common methods such as save, delete, findAll etc.
When you run above program, you will get below output:
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 <clinit>
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 <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
Sep 13, 2016 12:36:17 PM org.hibernate.dialect.Dialect <init>
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 <init>
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 <init>
INFO: HHH000261: Table found: CountryData.country
Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000037: Columns: [countryname, id, population]
Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000108: Foreign keys: []
Sep 13, 2016 12:36:18 PM org.hibernate.tool.hbm2ddl.TableMetadata <init>
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

Written by Arpit:

If you have read the post and liked it. Please connect with me on Facebook | Twitter | Google Plus

 

Java tutorial for beginners Copyright © 2012