Spring JPA is not a JPA provider but a specification. It is a library/framework that adds an extra layer of abstraction to the top of the JPA provider. It hides the Java Persistence API and the JPA provider behind its repository abstraction.
Features of Spring Data JPA:
- It creates and supports repositories created with spring and JPA.
- It supports JPA queries.
- It supports batch loading, sorting, and dynamical queries.
- It supports XML mapping for entities.
- It reduces the code size for generic CRUD operations by using the Crud Repository.
Components needed:
- The JDBC driver that enables Java applications to interact with the database.
- The data source that will provide all technical information needed to access data.
- The JPA Provider that will implement the Java Persistence API. We also use Hibernate because it is the most common JPA provider.
- Spring Data JPA that will hide the used JPA provider behind its repository abstraction.
The Java Persistence API is used for managing, persisting, and accessing data between objects and the relational database. Hibernate is an ORM (Object Relational Mapping) tool that implements JPA specification.
The below program illustrates how to integrate spring with JPA using the Hibernate as a JPA provider:
Step 1: 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>com.innovationM.hibernate</groupId> Â Â <artifactId>spring-hibernate-jpa-example</artifactId> Â Â <version>0.0.1-SNAPSHOT</version> Â Â <packaging>jar</packaging> Â Â <name>spring-hibernate-jpa-tutorial</name> Â Â <url>http://maven.apache.org</url> Â Â <properties> Â Â Â Â <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> Â Â </properties> Â Â <dependencies> Â Â Â Â <dependency> Â Â Â Â Â Â <groupId>org.springframework</groupId> Â Â Â Â Â Â <artifactId>spring-context</artifactId> Â Â Â Â Â Â <version>4.3.7.RELEASE</version> Â Â Â Â </dependency> Â Â Â Â <dependency> Â Â Â Â Â Â <groupId>org.springframework</groupId> Â Â Â Â Â Â <artifactId>spring-orm</artifactId> Â Â Â Â Â Â <version>4.3.7.RELEASE</version> Â Â Â Â </dependency> Â Â Â Â <dependency> Â Â Â Â Â Â <groupId>org.hibernate</groupId> Â Â Â Â Â Â <artifactId>hibernate-core</artifactId> Â Â Â Â Â Â <version>5.2.9.Final</version> Â Â Â Â </dependency> Â Â Â Â <dependency> Â Â Â Â Â Â <groupId>org.apache.commons</groupId> Â Â Â Â Â Â <artifactId>commons-dbcp2</artifactId> Â Â Â Â Â Â <version>2.1.1</version> Â Â Â Â </dependency> Â Â Â Â <dependency>Â Â Â Â Â Â Â <groupId>mysql</groupId>Â Â Â Â Â Â Â <artifactId>mysql-connector-java</artifactId>Â Â Â Â Â Â Â <version>6.0.5</version>Â Â Â Â Â </dependency> Â Â </dependencies> Â Â <build> Â Â Â Â <sourceDirectory>src/main/java</sourceDirectory> Â Â Â Â <plugins> Â Â Â Â Â Â <plugin> Â Â Â Â Â Â Â Â <artifactId>maven-compiler-plugin</artifactId> Â Â Â Â Â Â Â Â <version>3.5.1</version> Â Â Â Â Â Â Â Â <configuration> Â Â Â Â Â Â Â Â Â Â <source>1.8</source> Â Â Â Â Â Â Â Â Â Â <target>1.8</target> Â Â Â Â Â Â Â Â </configuration> Â Â Â Â Â Â </plugin> Â Â Â Â </plugins> Â Â </build> </project>
Step 2: Create a JPA entity class using setter and getter methods.
package com.innovationM.spring.entity; import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.GenerationType; import javax.persistence.Table; @Entity @Table(name = "PERSONS") public class Person {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;    @Column(name = "FIRST_NAME")    private String firstName;    @Column(name = "LAST_NAME")    private String lastName;    @Column(name = "EMAIL")    private String email;    public Person() {}    public Person(String firstName, String lastName, String email) {       this.firstName = firstName;       this.lastName = lastName;       this.email = email;    }    //getter and setter methods. }
Step 3: Create PersonDao.java. It will contain all the methods implemented by implementation class.
package com.innovationM.spring.dao; import java.util.List; import com.innovationM.spring.entity.Person; public interface PersonDao { Â Â Â void add(Person person); Â Â Â List<Person> listPersons(); }
Step 4: Create PersonDaoImp.java that will provide a method body to persist data in the database.
package com.innovationM.spring.dao; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; import org.springframework.stereotype.Repository; import com.innovationM.spring.entity.Person; @Repository public class PersonDaoImp implements PersonDao {    @PersistenceContext    private EntityManager em;    @Override    public void add(Person person) {       em.persist(person);    }    @Override    public List<Person> listPersons() {       CriteriaQuery<Person> criteriaQuery = em.getCriteriaBuilder().createQuery(Person.class);       @SuppressWarnings("unused")       Root<Person> root = criteriaQuery.from(Person.class);       return em.createQuery(criteriaQuery).getResultList();    } }
Step 5: Create PersonService.java
package com.innovationM.spring.service; import java.util.List; import com.innovationM.spring.entity.Person; public interface PersonService { Â Â Â Â void add(Person person); Â Â Â Â List<Person> listPersons(); }
Step 6: Create PersonServiceImp.java
package com.innovationM.spring.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.innovationM.spring.dao.PersonDao; import com.innovationM.spring.entity.Person; @Service public class PersonServiceImp implements PersonService {    @Autowired    private PersonDao userDao;    @Transactional    public void add(Person person) {       userDao.add(person);    }    @Transactional(readOnly = true)    public List<Person> listPersons() {       return userDao.listPersons();    } }
Step 7: persistence.xml file which will connect with the database.
<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="LOCAL_PERSISTENCE">     <description> Spring Hibernate JPA Configuration Example</description>     <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>     <properties>       <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />       <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/demo" />       <property name="javax.persistence.jdbc.user" value="root" />       <property name="javax.persistence.jdbc.password" value="root" />       <property name="hibernate.show_sql" value="true" />       <property name="hibernate.hbm2ddl.auto" value="update" />     </properties>   </persistence-unit> </persistence>
Step 8: Create Spring configuration class.
package com.innovationM.spring.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScans; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @ComponentScans(value = { @ComponentScan("com.innovationM.spring.dao"),       @ComponentScan("com.innovationM.spring.service") }) public class AppConfig {    @Bean    public LocalEntityManagerFactoryBean geEntityManagerFactoryBean() {       LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();       factoryBean.setPersistenceUnitName("LOCAL_PERSISTENCE");       return factoryBean;    }    @Bean    public JpaTransactionManager geJpaTransactionManager() {       JpaTransactionManager transactionManager = new JpaTransactionManager();       transactionManager.setEntityManagerFactory(geEntityManagerFactoryBean().getObject());       return transactionManager;    } }
Step 9: Create a main class to run the application.
package com.innovationM.spring; import java.sql.SQLException; import java.util.List; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.innovationM.spring.config.AppConfig; import com.innovationM.spring.entity.Person; import com.innovationM.spring.service.PersonService; public class MainApp {    public static void main(String[] arg) throws SQLException {       AnnotationConfigApplicationContext context =             new AnnotationConfigApplicationContext(AppConfig.class);       PersonService personService = context.getBean(PersonService.class);       // Add Persons       personService.add(new Person("Rahul", "Gupta", "[email protected]"));       personService.add(new Person("Akshay", "Sharma", "[email protected]"));       personService.add(new Person("Ankit", "Sarraf", "[email protected]"));       // Get Persons       List<Person> persons = personService.listPersons();       for (Person person : persons) {          System.out.println("Id = "+person.getId());          System.out.println("First Name = "+person.getFirstName());          System.out.println("Last Name = "+person.getLastName());          System.out.println("Email = "+person.getEmail());          System.out.println();       }       context.close();    } }
Output on the console will be:
Hibernate: insert into PERSONS (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
Hibernate: insert into PERSONS (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
Hibernate: insert into PERSONS (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
Hibernate: select person0_.id as id1_0_, person0_.EMAIL as EMAIL2_0_, person0_.FIRST_NAME as FIRST_NA3_0_, person0_.LAST_NAME as LAST_NAM4_0_ from PERSONS person0_
Id = 1
First Name = Rahul
Last Name = Gupta
Email = [email protected]
Id = 2
First Name = Akshay
Last Name = Sharma
Email = [email protected]
Id = 3
First Name = Ankit
Last Name = Sarraf
Email = [email protected]