In this Spring Boot JPA Tutorial, we will integrate Spring Data JPA into our Spring Boot application. Our Employee management application will be extending CRUDRepository which in turn extends the Repository interface.
Creating table
Create EMPLOYEE Table, simply Copy and Paste the following SQL query in the query editor to get the table created.
CREATE TABLE "EMPLOYEE" ( "ID" NUMBER(10,0) NOT NULL ENABLE, "NAME" VARCHAR2(255 CHAR), "AGE" NUMBER(10,0) NOT NULL ENABLE, "DEPT" VARCHAR2(255 CHAR), PRIMARY KEY ("ID") ); insert into "EMPLOYEE" values (1,'JIP1',11,'IT'); insert into "EMPLOYEE" values (2,'JIP2',22,'IT'); insert into "EMPLOYEE" values (3,'JIP3',33,'IT'); insert into "EMPLOYEE" values (4,'JIP4',44,'IT');
Spring Boot JPA Tutorial – CrudRepository
Folder Structure:
- Create a simple Maven Project “SpringBootJPA” by selecting maven-archetype-quickstart and create a package for our source files “com.javainterviewpoint” under src/main/java
- Now add the following dependency in the POM.xml
<?xml version="1.0" encoding="UTF-8"?> <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.javainterviewpoint</groupId> <artifactId>SpringBootJPA</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc14</artifactId> <version>11.2.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
- Create the Java classes App.java,Employee.java and EmployeeRepository.java under com.javainterviewpoint folder.
The spring-boot-starter-parent is a special starter, it provides useful Maven defaults. We will be using two using two additional Spring Boot Starters spring-boot-starter-data-jpa apart from spring-boot-starter-parent.
Dependency Tree
$ mvn dependency:tree [INFO] ------------------------------------------------------------------------ [INFO] Building SpringBootJPA 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ SpringBootJPA --- [INFO] com.javainterviewpoint:SpringBootJPA:jar:0.0.1-SNAPSHOT [INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:1.5.1.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:1.5.1.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot:jar:1.5.1.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.1.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:1.5.1.RELEASE:compile [INFO] | | | +- ch.qos.logback:logback-classic:jar:1.1.9:compile [INFO] | | | | \- ch.qos.logback:logback-core:jar:1.1.9:compile [INFO] | | | +- org.slf4j:jul-to-slf4j:jar:1.7.22:compile [INFO] | | | \- org.slf4j:log4j-over-slf4j:jar:1.7.22:compile [INFO] | | +- org.springframework:spring-core:jar:4.3.6.RELEASE:compile [INFO] | | \- org.yaml:snakeyaml:jar:1.17:runtime [INFO] | +- org.springframework.boot:spring-boot-starter-aop:jar:1.5.1.RELEASE:compile [INFO] | | +- org.springframework:spring-aop:jar:4.3.6.RELEASE:compile [INFO] | | \- org.aspectj:aspectjweaver:jar:1.8.9:compile [INFO] | +- org.springframework.boot:spring-boot-starter-jdbc:jar:1.5.1.RELEASE:compile [INFO] | | +- org.apache.tomcat:tomcat-jdbc:jar:8.5.11:compile [INFO] | | | \- org.apache.tomcat:tomcat-juli:jar:8.5.11:compile [INFO] | | \- org.springframework:spring-jdbc:jar:4.3.6.RELEASE:compile [INFO] | +- org.hibernate:hibernate-core:jar:5.0.11.Final:compile [INFO] | | +- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile [INFO] | | +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile [INFO] | | +- org.javassist:javassist:jar:3.21.0-GA:compile [INFO] | | +- antlr:antlr:jar:2.7.7:compile [INFO] | | +- org.jboss:jandex:jar:2.0.0.Final:compile [INFO] | | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | | \- org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile [INFO] | +- org.hibernate:hibernate-entitymanager:jar:5.0.11.Final:compile [INFO] | +- javax.transaction:javax.transaction-api:jar:1.2:compile [INFO] | +- org.springframework.data:spring-data-jpa:jar:1.11.0.RELEASE:compile [INFO] | | +- org.springframework.data:spring-data-commons:jar:1.13.0.RELEASE:compile [INFO] | | +- org.springframework:spring-orm:jar:4.3.6.RELEASE:compile [INFO] | | +- org.springframework:spring-context:jar:4.3.6.RELEASE:compile [INFO] | | | \- org.springframework:spring-expression:jar:4.3.6.RELEASE:compile [INFO] | | +- org.springframework:spring-tx:jar:4.3.6.RELEASE:compile [INFO] | | +- org.springframework:spring-beans:jar:4.3.6.RELEASE:compile [INFO] | | +- org.slf4j:slf4j-api:jar:1.7.22:compile [INFO] | | \- org.slf4j:jcl-over-slf4j:jar:1.7.22:compile [INFO] | \- org.springframework:spring-aspects:jar:4.3.6.RELEASE:compile [INFO] \- com.oracle:ojdbc14:jar:11.2.0:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 4.852s [INFO] Finished at: Wed Jul 11 17:44:14 IST 2018 [INFO] Final Memory: 15M/225M [INFO] ------------------------------------------------------------------------
application.properties
Place the application.properties file under the src/resources folder
#Oracle Connection settings spring.datasource.url=jdbc:oracle:thin:@rsh2:40051:mydb spring.datasource.username=root spring.datasource.password=password spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver #JPA properties spring.jpa.show-sql = true spring.jpa.hibernate.ddl-auto = update
Spring Data JPA CrudRepository [EmployeeRepository.java]
package com.javainteriviewpoint; import java.util.List; import org.springframework.data.repository.CrudRepository; public interface EmployeeRepository extends CrudRepository<Employee, Long> { public List findById(long id); //@Query("select e from Employee s where e.age <= ?") public List findByAgeLessThanEqual (long age); }
Spring Data JPA will create an implementation of EmployeeRepository automatically during runtime.
Spring Data Repository has the query builder mechanism built in which strips the prefixes find…By, read…By, and get…By . We have used the the same query builder mechanism and created our custom method findById() and findByAgeLessThanEqual()
In the Spring Data we can also add expressions with AND / OR and it also supports operators such as Between, LessThan, GreaterThan, Like
App.java
package com.javainteriviewpoint; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(scanBasePackages = { "com.javainterviewpoint" }) public class App implements CommandLineRunner { @Autowired EmployeeRepository employeeRepository; public static void main(String[] args) { SpringApplication.run(App.class, args); } @Override public void run(String... args) throws Exception { /** Create **/ System.out.println("***** Saving a new Employee *******"); Employee employee = new Employee(); employee.setName("New Employee"); employee.setAge(44); employee.setDept("Blog"); employeeRepository.save(employee); /** Read **/ // Getting all Employees System.out.println("***** All Employees *******"); for(Employee emp : employeeRepository.findAll()) { System.out.println(emp); } // Getting the Employees with id 2 System.out.println("***** Employee with ID 2 *******"); for(Employee emp : employeeRepository.findById(2)) { System.out.println(emp); } /** Update **/ Employee employee1 = new Employee(); employee1.setId(4); employee1.setName("New Employee111"); employee1.setAge(44); employee1.setDept("Blog"); employeeRepository.save(employee1); /** Delete **/ // Delete the Employees with id 2 employeeRepository.delete((long) 4); } }
- @SpringBootApplication annotation does the work of @EnableAutoConfiguration, @Configuration and @ComponentScan annotations together
- CommandLineRunner interface has an unimplemented run() method, In our App class we have implemented the CommandLineRunner interface and have overridden the run() method.
- When the SpringApplication.run() of the App class starts the spring boot application just before the application gets started, CommandLineRunner.run() will be executed.
- We will be performing the CRUD (Create, Read, Update, Delete) operations in the overridden run() method.
- Create – Create a new Employee object, set the values to its properties and pass it to the save() method of the employeeRepository instance.
- Read – Just call the findAll() or Pass the employee id to the findById() of the employeeRepository class
- Update – Pass the modified employee object to the save() method of the employeeRepository instance.
- Delete – Pass the employee id to the delete() of the employeeRepository class
The JPA Entity – Employee.java
package com.javainteriviewpoint; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Employee { @Id @GeneratedValue @Column(name="ID") private long id; @Column(name="NAME") private String name; @Column(name="AGE") private long age; @Column(name="DEPT") private String dept; public Employee() { super(); } public Employee(long id, String name, long age, String dept) { super(); this.id = id; this.name = name; this.age = age; this.dept = dept; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getAge() { return age; } public void setAge(long age) { this.age = age; } public String getDept() { return dept; } public void setDept(String dept) { this.dept = dept; } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", dept=" + dept + "]"; } }
Our Employee class is our JPA entity class consisting of the getters and setters for the Employee class properties (id, name, age, dept).
In the POJO class, we have used the below JPA Annotations.
- @Entity – This annotation will mark our Employee class as an Entity Bean.
- @Table – @Table annotation will map our class to the corresponding database table. You can also specify other attributes such as indexes, catalog, schema, uniqueConstraints. The @Table annotation is an optional annotation if this annotation is not provided then the class name will be used as the table name.
- @Id – The @Id annotation marks the particular field as the primary key of the Entity.
- @GeneratedValue – This annotation is used to specify how the primary key should be generated. Here SEQUENCE Strategy will be used as this the default strategy for Oracle
Output
Run our application [app.java] using the command “mvn spring-boot:run”, you will get the below output
***** Saving a new Employee ******* Hibernate: select employee0_.id as id1_0_0_, employee0_.age as age2_0_0_, employee0_.dept as dept3_0_0_, employee0_.name as name4_0_0_ from employee employee0_ where employee0_.id=? Hibernate: insert into employee (age, dept, name, id) values (?, ?, ?, ?) ***** All Employees ******* 2018-07-11 17:48:39.001 INFO 11100 --- [ main] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory Hibernate: select employee0_.id as id1_0_, employee0_.age as age2_0_, employee0_.dept as dept3_0_, employee0_.name as name4_0_ from employee employee0_ Employee [id=1, name=JIP1, age=11, dept=IT] Employee [id=2, name=JIP2, age=22, dept=IT] Employee [id=3, name=JIP3, age=33, dept=IT] Employee [id=4, name=New Employee, age=44, dept=Blog] ***** Employee with ID 2 ******* Hibernate: select employee0_.id as id1_0_, employee0_.age as age2_0_, employee0_.dept as dept3_0_, employee0_.name as name4_0_ from employee employee0_ where employee0_.id=? Employee [id=2, name=JIP2, age=22, dept=IT] Hibernate: select employee0_.id as id1_0_0_, employee0_.age as age2_0_0_, employee0_.dept as dept3_0_0_, employee0_.name as name4_0_0_ from employee employee0_ where employee0_.id=? Hibernate: update employee set age=?, dept=?, name=? where id=? Hibernate: select employee0_.id as id1_0_0_, employee0_.age as age2_0_0_, employee0_.dept as dept3_0_0_, employee0_.name as name4_0_0_ from employee employee0_ where employee0_.id=? Hibernate: delete from employee where id=?
Leave a Reply