HowToDoInJava

  • Java 8
  • Regex
  • Concurrency
  • Best Practices
  • Spring Boot
  • JUnit5
  • Interview Questions
  • Dark Mode

Spring REST CRUD Example with JPA Configuration

By Lokesh Gupta | Filed Under: Spring REST

Learn to create REST APIs for crud operations using Spring REST and JPA configuration (H2 database as backend) without Spring boot auto configuration feature.

1. Maven dependencies

In this example, we are using following modules and their dependencies.

  • spring-webmvc – for request handling
  • spring-data-jpa – provides interfaces with methods supporting reading, updating, deleting, and creating records against a back end data store.
  • persistence-api – JPA specification
  • javax.persistence – JPA implementation
  • hibernate-entitymanager – as entity maneger provider
  • Jackson – for JSON support
  • H2 – as database
<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.howtodoinjava.rest</groupId>
	<artifactId>SpringRestExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>SpringRestExample</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring.version>5.1.6.RELEASE</spring.version>
		<maven.compiler.source>1.8</maven.compiler.source>
    	<maven.compiler.target>1.8</maven.compiler.target>
	</properties>

	<dependencies>
		<!-- spring webmvc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
		<!-- spring data jpa -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>2.1.6.RELEASE</version>
		</dependency>
		
		<!-- persistence api -->
		<dependency>
			<groupId>javax.persistence</groupId>
			<artifactId>persistence-api</artifactId>
			<version>1.0.2</version>
		</dependency>
		
		<!-- persistence implementation -->
		<dependency>
			<groupId>org.eclipse.persistence</groupId>
			<artifactId>javax.persistence</artifactId>
			<version>2.1.0</version>
		</dependency>
		
		<!-- entity manager provider -->
		<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.4.2.Final</version>
        </dependency>
        
        <!-- H2 database -->
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<version>1.4.199</version> 
		</dependency>
		
		<!-- JSON support -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.8</version>
		</dependency>
	</dependencies>
</project>

2. DispatcherServlet declaration

We have configured the DispatcherServlet in web.xml file which will route the incoming requests to appropriate controller methods.

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
	<display-name>Employee Management REST APIs</display-name>

	<servlet>
		<servlet-name>rest</servlet-name> 
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>rest</servlet-name>
		<url-pattern>/api/rest/*</url-pattern>
	</servlet-mapping>

</web-app>

3. Spring and JPA configuration

In rest-servlet.xml file we have configured the component scanning and annotation based config support. Along with it, we have configured the entity manager and datasource configuration.

<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"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:tx="http://www.springframework.org/schema/tx"
	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
	http://www.springframework.org/schema/data/jpa 
    http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/mvc
	http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<context:component-scan base-package="com.howtodoinjava.demo" />
	<mvc:annotation-driven />
	<jpa:repositories base-package="com.howtodoinjava.demo.repository" entity-manager-factory-ref="emf"/>
	
	<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	    <property name="packagesToScan" value="com.howtodoinjava.demo.model" />
	    <property name="dataSource" ref="dataSource" />
	
	    <property name="jpaProperties">
	        <props>
	            <prop key="hibernate.show_sql">true</prop>
	            <prop key="hibernate.format_sql">true</prop>
	            <prop key="hibernate.hbm2ddl.auto">create</prop>
	            <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
	        </props>
	    </property>
	
	    <property name="persistenceProvider">
	        <bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
	    </property>
	
	</bean>
	
	<bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource" id="dataSource">
        <property name="driverClass" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;TRACE_LEVEL_SYSTEM_OUT=2" />
    </bean>
	
	<tx:annotation-driven transaction-manager="transactionManager" />
	
	<bean class="org.springframework.orm.jpa.JpaTransactionManager"  id="transactionManager">
	    <property name="dataSource" ref="dataSource" />
	</bean>
</beans>

4. Entity class

We have only one entity class which will be persisted in DB and will be returned as response from REST APIs.

  • @Entity – JPA annotation to make the object ready for storage in a JPA-based data store.
  • @Table – Name of the table in data storage where this entity will be stored.

Read More : JPA 2 Persistence Annotations

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tbl_employee")
public class Employee implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	private String firstName;

	private String lastName;

	private String email;

	public Employee() {
	}

	//Getters and setters

	@Override
	public String toString() {
		return "EmployeeVO [id=" + id + ", firstName=" + firstName + ", 
				lastName=" + lastName + ", email=" + email	+ "]";
	}
}

5. Repository

We have created JpaRepository implementation as EmployeeRepository which provides all defaults operations for performing search, get, update and delete operations on employee entities.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.howtodoinjava.demo.model.Employee;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

}

6. REST Controller

The REST controller defines all CRUD methods which can be invoked to perform operations on employee resource.

In given controller, @RestController annotation indicates that the data returned by the methods will be written straight into the response body instead of rendering a template. Other annotations (@GetMapping, @PostMapping, @PutMapping and @DeleteMapping) map the HTTP requests to corresponding methods.

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.howtodoinjava.demo.model.Employee;
import com.howtodoinjava.demo.repository.EmployeeRepository;

@RestController
@RequestMapping(value = "/employee-management", produces = { MediaType.APPLICATION_JSON_VALUE })
public class EmployeeRESTController 
{
	@Autowired
	private EmployeeRepository repository;

	public EmployeeRepository getRepository() {
		return repository;
	}

	public void setRepository(EmployeeRepository repository) {
		this.repository = repository;
	}

	@GetMapping(value = "/employees")
	public List<Employee> getAllEmployees() {
		return repository.findAll();
	}

	@PostMapping("/employees")
	Employee createOrSaveEmployee(@RequestBody Employee newEmployee) {
		return repository.save(newEmployee);
	}

	@GetMapping("/employees/{id}")
	Employee getEmployeeById(@PathVariable Long id) {
		return repository.findById(id).get();
	}

	@PutMapping("/employees/{id}")
	Employee updateEmployee(@RequestBody Employee newEmployee, @PathVariable Long id) {

		return repository.findById(id).map(employee -> {
			employee.setFirstName(newEmployee.getFirstName());
			employee.setLastName(newEmployee.getLastName());
			employee.setEmail(newEmployee.getEmail());
			return repository.save(employee);
		}).orElseGet(() -> {
			newEmployee.setId(id);
			return repository.save(newEmployee);
		});
	}

	@DeleteMapping("/employees/{id}")
	void deleteEmployee(@PathVariable Long id) {
		repository.deleteById(id);
	}
}

7. Spring REST CRUD Operations Demo

Let’s test the API operations to validate they work.

7.1. Create employee

HTTP POST : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees

{
    "firstName": "lokesh",
    "lastName": "gupta",
    "email": "abc@gmail.com"
}
HTTP Response code : 200

{
	"id": 1,
	"firstName": "lokesh",
	"lastName": "gupta",
	"email": "abc@gmail.com"
}

Create few more employees for testing.

7.2. Get employees collection

HTTP GET : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees
HTTP Response code : 200

[
	{
		"id": 1,
		"firstName": "lokesh",
		"lastName": "gupta",
		"email": "abc@gmail.com"
	},
	{
		"id": 2,
		"firstName": "Amit",
		"lastName": "Sharma",
		"email": "xyz@gmail.com"
	}
]

7.3. Get employee by id

HTTP GET : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/1
HTTP Response code : 200

{
	"id": 1,
	"firstName": "lokesh",
	"lastName": "gupta",
	"email": "abc@gmail.com"
}

7.4. Update employee

HTTP PUT : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/1

{
    "firstName": "Lucky",
    "lastName": "Gupta",
    "email": "abc@gmail.com"
}
HTTP Response code : 200

{
	"id": 1,
	"firstName": "Lucky",
	"lastName": "Gupta",
	"email": "abc@gmail.com"
}

7.5. Delete employee

HTTP DELETE : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/1
HTTP Response code : 200

Happy Learning !!

Sourcecode Download

TwitterFacebookLinkedinRedditPocket

About Lokesh Gupta

A family guy with fun loving nature. Love computers, programming and solving everyday problems. Find me on Facebook and Twitter.

3
Leave a Reply

This comment form is under antispam protection
2 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
This comment form is under antispam protection
  Subscribe  
newest oldest most voted
Notify of
vivek

Can we add multiple AUTH_API_KEY for different users? Or alternatively authorize users using credentials from database?

Vote Up0Vote Down  Reply
5 months ago
anonymos

So much easier with springboot 🙂

Vote Up0Vote Down  Reply
7 months ago
Lokesh Gupta

True. That is covered here.

Vote Up0Vote Down  Reply
7 months ago

Search Tutorials

Spring REST Tutorials

  • Spring REST – JSON
  • Spring REST – XML
  • Spring REST – Controller
  • Spring REST – CRUD App
  • Spring REST – Exception Handler
  • Spring REST – Request Validation
  • Spring REST – Custom Token Auth
  • Spring REST – Multipart
  • Spring REST – Multiple uploads
  • Spring REST – OPTIONS Handler
  • Spring REST – Access denied JSON
  • Spring REST – RestTemplate

Popular Tutorials

  • Java 8 Tutorial
  • Core Java Tutorial
  • Collections in Java
  • Java Concurrency
  • Spring Boot Tutorial
  • Spring AOP Tutorial
  • Spring MVC Tutorial
  • Spring Security Tutorial
  • Hibernate Tutorial
  • Python Tutorial
  • Jersey Tutorial
  • Maven Tutorial
  • Log4j Tutorial
  • Regex Tutorial

Meta Links

  • Advertise
  • Contact Us
  • Privacy policy
  • About Me

Recommended Reading

  • 10 Life Lessons
  • Secure Hash Algorithms
  • How Web Servers work?
  • How Java I/O Works Internally?
  • Best Way to Learn Java
  • Java Best Practices Guide
  • Microservices Tutorial
  • REST API Tutorial
  • How to Start New Blog

Copyright © 2016 · HowToDoInjava.com · All Rights Reserved. | Sitemap

wpDiscuz