CRUD Rest Service With Spring Boot and JPA:-

Spring framework has become a platform for almost every development task. You can set up a project and start building very fast.In this article, we are going to build a CRUD Rest Service With Spring Boot and Jpa to manage users. We are going to use the same code throughout our series on spring boot and test the application using a RestClient "Postman". Please visit my previous post and do necessary steps here to create a project.I request you to keep patience as this article is gonna be quite long.

So, Let's get Started !!

Project Structure:-

We are creating different packages for Beans, Controllers, Repository, and Services. Let's go ahead and create following package structure as shown below. We are going to see each and every package and its functionalities one by one with code.

//pagead2.googlesyndication.com/pagead/js/adsbygoogle

SampleRestApplication.java:-

It is the entry point of Spring Boot application.We are going to annotate our class with @ComponentScan and indicate the base package to scan for spring beans. It contains @SpringBootApplication annotation which is basically a combination of the following annotations.

@Configuration @EnableAutoConfiguration @ComponentScan

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication @ComponentScan(basePackages="com.frugalis") @EnableJpaRepositories(basePackages="com.frugalis.repository") @EntityScan(basePackages="com.frugalis.entity") public class SampleRestApplication { public static void main(String\[\] args) { SpringApplication.run(SampleRestApplication.class, args); } }

We are using two more annotations:-

@EntityScan:- This annotation Scans for all persistence based beans in your defined package. @EnableJpaRepositories:- This annotation enables Spring Data JPA repositories support in your application.

User.java:-

We are going to create a simple bean to accept input and return as an output.

import java.io.Serializable; public class User implements Serializable { Long id; String firstname; String lastname; String institute; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getInstitute() { return institute; } public void setInstitute(String institute) { this.institute = institute; } }

//pagead2.googlesyndication.com/pagead/js/adsbygoogle

Configure Mysql Database:-

We are already adding the spring-data-jpa dependency in our maven configuration. So spring-data-jpa is already in the classpath. It automatically tries to configure a DataSource by reading the database specific properties from the file. application.properties

Let's add the database configuration in file application.properties and spring automatically going to load at runtime. Create a database schema called springboot in MySQL .

spring.datasource.password= spring.jpa.hibernate.ddl-auto=create-drop server.port=8088

Replace your database credentials in properties spring.datasource.username and spring.datasource.password . The property spring.jpa.hibernate.ddl-auto can have two values create-drop and update . create-drop will drop and recreate the existing database entity whereas update will update the existing database entity if any changes are there.

Create Domain Classes or Entity:-

We now create our User entity which is going to persist in our database. Our entity is going to have following set of fields.

id is pk of the entity firstname lastname institute

User.java:-

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="USERS") public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) Long id; String firstname; String lastname; String institute; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getInstitute() { return institute; } public void setInstitute(String institute) { this.institute = institute; } }

As we can see above , we are creating two User classes. User class as a simple plain POJO object and use it for sending as a response Object. Another One is User entity class because, we don't want to expose our entity object directly as a response, hence we are creating another POJO User object.

Access Users Data From Database:-

We are creating UserRepository to access data from database persisted by hibernate.Our repository class is going to extend JpaRepository.

Spring Data JPA aims to significantly improve the implementation of data access layers by reducing the effort to the amount that’s actually needed. As a developer you write your repository interfaces, including custom finder methods, and Spring will provide the implementation automatically.

UserRepository.java:-

import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import com.frugalis.entity.User; public interface UserRepository extends JpaRepository<User, Long>{ List<User> findByfirstname(String firstname); User findById(Long Id); }

You will now be able to use JpaRepository’s methods like save() , delete() , findAll() , delete() etc. The repository above extends JpaRepository , passes the JPA entity and its primary key.

Basic methods for finding a single record, all records, paginated records, create/update, and delete are automatically provided. It's also very easy to overload any custom query to add pagination and sorting.

The method findByfirstname lets Spring Data JPA automatically generate a like query for the first name column. We can also write query in JQL and execute like below in case we need it.

public List<Person> findByinstitute(@Param("institute") String institute);

Writing Our Business Service:-

We are almost done setting up our JPA , now we are going to use the repository and write our business logic.So we are going to do crud operations and declare our service methods in an interface and write separate implementations.

UserService.java:-

import java.util.List; import com.frugalis.beans.User; public interface UserService { public User saveUser(User inUser); public List<User> getAllUsers(); public User findbyId(Long id); }

The above interface gives you an idea how our business logic is going to be implemented , let's take a pause and write business service implementations one by one while creating Rest Implementations.

Writing Rest Implementations:-

Now we are actually going to do the rest implementations of the API.Let's Open our HelloController and start implementing one by one. We are first going to write code in our RestController and call business service class UserService from the controller for a particular endpoint.Create a class named UserServiceImpl implements UserService to write our business logic and implement all the methods.

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; 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.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.frugalis.beans.User; import com.frugalis.service.UserService; import com.mysql.cj.fabric.Response; @RestController public class HelloController { @Autowired UserService userService; //To DO all Rest Methods }

Spring 4.0 introduced @RestController, a specialized version of the controller which is a convenience annotation that does nothing more than adding the @Controller and @ResponseBody annotations. By annotating the controller class with @RestController annotation, you no longer need to add @ResponseBody to all the request mapping methods. The @ResponseBody annotation is active by default.

Testing and Execution:-

Let's see now how we are going to give final shape to our CRUD Rest Service With Spring Boot and JPA step by step.

1. Create a User:- Method is Post and EndPoint is /users

Add following line of code in HelloController.java

public ResponseEntity<User> getNoteById(@PathVariable(value = "id") Long userId) { User note = userService.findbyId(userId); if(note == null) { return ResponseEntity.notFound().build(); } return ResponseEntity.ok().body(note); }

This method tells us that the above code will be executed once a Post request with url is _**localhost****:8080/users**_ requested. We are using @__RequestBody which says that it expects user object in the body as JSON format.

Now that we have added our request mapping and write business logic in **UserServiceImpl.java.**

UserRepository userRepository; @Override public User saveUser(User inUser) { com.frugalis.entity.User outUser2 = new com.frugalis.entity.User(); BeanUtils.copyProperties(inUser, outUser2); outUser2 = userRepository.save(outUser2); BeanUtils.copyProperties(outUser2, inUser); return inUser; }

We are copying properties from User entity object to User Pojo using BeanUtils.copyProperties and returning a Pojo object from our service class.

Testing:-

2. Retrieve a User:- Method is GET and EndPoint is /users/{id}

Add following line of code in HelloController.java

public ResponseEntity<User> getUserById(@PathVariable(value = "id") Long userId) { User user = userService.findbyId(userId); if(user == null) { return ResponseEntity.notFound().build(); } return ResponseEntity.ok().body(user); }

This method tells us that the above code will be executed once a GET request with url is _**localhost****:8080/users/1**_ requested. We are using RestEntity which says that returns a User Object .

Now that we have added our request mapping and write business logic in **UserServiceImpl.java.**

public User findbyId(Long id) { // TODO Auto-generated method stub com.frugalis.entity.User dbUser=userRepository.findById(id); User outUser=null; if(dbUser!=null){ outUser=new User(); BeanUtils.copyProperties(dbUser, outUser); } return outUser; }

We are copying properties from dbUser entity object to User Pojo using BeanUtils.copyProperties and returning a Pojo object from our service class.Lets run our Project using **mvn Spring-boot:run**

Testing:-

3. Update a User:- Method is PUT and EndPoint is /users/{id}

Add following line of code in HelloController.java

public ResponseEntity<Object> updateUser(@PathVariable(value = "id") Long userId,@RequestBody User inUser) { inUser.setId(userId); User user = userService.updateUser(inUser); if(user == null) { return ResponseEntity.ok().body(new String("Not Found")); } return ResponseEntity.ok().body(user); }

This method tells us that the above code will be executed once a PUT request with url is _**localhost****:8080/users/1**_ requested. We are using ResponseEntity which says that returns any Object .

Now that we have added our request mapping and write business logic in **UserServiceImpl.java.**

public User updateUser(User inUser) { // TODO Auto-generated method stub com.frugalis.entity.User dbUser=userRepository.findById(inUser.getId()); if(dbUser!=null){dbUser.setFirstname(inUser.getFirstname()); dbUser.setInstitute(inUser.getInstitute()); dbUser.setLastname(inUser.getLastname()); userRepository.save(dbUser); BeanUtils.copyProperties(dbUser, inUser); return inUser; }else { return null; } }

Testing:-

3. Delete a User:- Method is DELETE and EndPoint is /users/{id}

Add following line of code in HelloController.java

public ResponseEntity<Object> deleteUser(@PathVariable(value = "id") Long userId) { int user = userService.deleteUser(userId); if(user<=0) { return ResponseEntity.ok().body(new String("Not Found")); } return ResponseEntity.ok().body(new String("Deleted SuccessFully")); }

This method tells us that the above code will be executed once a DELETE request with url is _**localhost****:8080/users/1**_ requested. We are using ResponseEntity which says that returns any Object.

Now that we have added our request mapping and write business logic in **UserServiceImpl.java.**

public int deleteUser(Long id) { try{ com.frugalis.entity.User dbUser=userRepository.findById(id); if(dbUser==null){return -1;} else { userRepository.delete(id); return 1; } }catch(Exception e){ } return 0; }

Testing:-

Download Code