CodeTreat

Full Stack Developer Tutorials

  • About
Spring Boot, Data JPA, Hibernate with MS SQL Server RESTful CRUD app – Part 2

Spring Boot, Data JPA, Hibernate with MS SQL Server RESTful CRUD app – Part 2

In the previous tutorial, we built a REST API with Read functionality. In this second part of the tutorial, let us focus on performing the other operations such as Create, Update and Delete of the CRUD operations. Let us make changes to the files that we created in the first part.

Domain Model/Entity


package com.codetreat.sample.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

@Entity
@Table(name = "Sample")
public class SampleEntity {

	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	Long Id;

	@NotNull
	@Column(name = "name")
	String name;

	@NotNull
	@Column(name = "age")
	Integer age;

	public Long getId() {
		return Id;
	}

	public void setId(Long id) {
		Id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

}
  • @GeneratedValue – We have added this annotation to the @Id column of the entity in-order to denote that the primary key id should be an auto-generated one. In the strategy field, we specify the type of ID generator to be used. In our case, we have specified it as IDENTITY. If you use MySQL DB, you may have to use the AUTO type and for Oracle, you may use SEQUENCE.
  • @NotNull – This annotation can be added to the column names to denote that the specific column should not contain any null values. This is a validator annotation.

Repository


In the repository, we already defined a method named getAll() which was annotated with the annotation @Query in which we specified the SELECT query to be used to fetch the data from the table. In fact, we can ignore using the @Query annotation, since JPA comes with inbuilt methods to perform the CRUD operations. Instead of extending the CrudRepository interface in the SampleRepository.java, let us extend the JpaRepository Interface as shown below.

package com.codetreat.sample.repository;

import java.util.List;

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

import com.codetreat.sample.entity.SampleEntity;

@Repository
public interface SampleRepository extends JpaRepository<SampleEntity, Long> {

}

Note that we have removed the method getAll() which we used in the previous tutorial to fetch all records from the table. In the SampleService class, we will implement the inbuilt methods of the JpaRepository interface to perform CRUD operations.

Service


In the SampleService class, we are going to create three new methods in which we will write the business logic to perform the Create, Update and Delete operations.

Create

public SampleEntity createSample(SampleEntity sampleEntity) {
	return sampleRepo.save(sampleEntity);
}

In the above method, we have utilized the save() method, which is the default method that is defined in the JpaRepository interface to save/persist an entity to the database. By passing the SampleEntity object to the save method, we denote that the changes made the entity must be persisted in the database.

Update

public SampleEntity updateSample(Long Id, SampleEntity sampleEntity) {
	SampleEntity updatedSample;
	Optional<SampleEntity> searchEntity = sampleRepo.findById(Id);
	if (searchEntity.isPresent()) {
		SampleEntity sample = searchEntity.get();
		sample.setAge(sampleEntity.getAge());
		sample.setName(sampleEntity.getName());
		updatedSample = sampleRepo.save(sample);
	} else {
		throw new EntityNotFoundException();
	}
	return updatedSample;
}

We have created a new method named updateSample in which we have defined the logic to update our entity and persist it in the database. We have passed two parameters Id and sampleEntity to the method. The Id parameter is the primary key of the entity which will be used to search for the entity to be updated and the sampleEntity object is the entity that needs to be updated.

  • Inside the method, let us define a new object of Class SampleEntity in which the updated results will be stored.
  • Next, let us use the findById method which comes predefined in the JpaRespository, to search our entity and fetch the record. We have passed the Id value as the parameter of this method.
  • After that, we have created an if – else block which is used to check whether the searched entity is available in the DB, if so, we will updated the records and persist in the DB. Otherwise, we will throw the EntityNotFoundException.
  • Withing the if section of the block, we have checked the availability of the searched entity through the condition searchEntity.isPresent(). The isPresent() method is a utility method of the Optional class which was introduced in Java 8.
  • Optional – An Optional class is a container object used for storing not-null objects. It is used to represent a value with an empty/absent value. The best thing about an Optional class is that it helps you to avoid NullPointerException since it will consider null values as empty items.
  • After checking the condition, we will fetch the record using the get() method and update it using the setters and getters.
  • Finally, let us persist the updated entity using the save() method which comes with the JpaRepository interface to persist the entity. We have stored it in the object updatedSample which was created in the beginning of the method to stored the updated entity.
  • In the else block, we have throw a new EntityNotFoundException if no entities are found.
  • As the final part of the method, the updated entity has been returned as output of the method.

Delete

public ResponseEntity<Object> deleteSample(Long Id) {
	Optional<SampleEntity> sampleEntity = sampleRepo.findById(Id);
	if (sampleEntity.isPresent()) {
		SampleEntity sample = sampleEntity.get();
		sampleRepo.delete(sample);
	} else {
		throw new EntityNotFoundException();
	}
	return ResponseEntity.ok().build();
}

In a similar way they entity was updated through the updateSample method, let us created the deleteSample method to delete an entity. Here we have used the delete() method of JpaRepository interface to delete an entity. Finally we have returned a ResponseEntity object with the response as ok which actually returns a HTTP 200 OK response.

Read

public List<SampleEntity> getAll() {
	return (List<SampleEntity>) sampleRepo.findAll();
}

Finally, in the getAll method which we already created to fetch all the records from the table, we have made some changes by removing the getAll method which we defined in the SampleRepository and instead, we have used the findAll() method which comes predefined in the JpaRepository interface to fetch all records from the table.

The consolidated SampleService class should look as shown below.

package com.codetreat.sample.service;

import java.util.List;
import java.util.Optional;

import javax.persistence.EntityNotFoundException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import com.codetreat.sample.entity.SampleEntity;
import com.codetreat.sample.repository.SampleRepository;

@Service
public class SampleService {

	@Autowired
	SampleRepository sampleRepo;

	public List<SampleEntity> getAll() {
		return (List<SampleEntity>) sampleRepo.findAll();
	}

	public SampleEntity createSample(SampleEntity sampleEntity) {
		return sampleRepo.save(sampleEntity);
	}

	public SampleEntity updateSample(Long Id, SampleEntity sampleEntity) {
		SampleEntity updatedSample;
		Optional<SampleEntity> searchEntity = sampleRepo.findById(Id);
		if (searchEntity.isPresent()) {
			SampleEntity sample = searchEntity.get();
			sample.setAge(sampleEntity.getAge());
			sample.setName(sampleEntity.getName());
			updatedSample = sampleRepo.save(sample);
		} else {
			throw new EntityNotFoundException();
		}
		return updatedSample;
	}

	public ResponseEntity<Object> deleteSample(Long Id) {
		Optional<SampleEntity> sampleEntity = sampleRepo.findById(Id);
		if (sampleEntity.isPresent()) {
			SampleEntity sample = sampleEntity.get();
			sampleRepo.delete(sample);
		} else {
			throw new EntityNotFoundException();
		}
		return ResponseEntity.ok().build();
	}
}

Controller


package com.codetreat.sample.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.codetreat.sample.entity.SampleEntity;
import com.codetreat.sample.service.SampleService;

@RestController
public class SampleController {

	@Autowired
	SampleService sampleService;

	@RequestMapping(value = "/sample")
	public List<SampleEntity> sample() {
		return sampleService.getAll();
	}

	@RequestMapping(value = "/createsample", method = RequestMethod.POST)
	public SampleEntity createSample(@Valid @RequestBody SampleEntity sampleEntity) {
		return sampleService.createSample(sampleEntity);
	}

	@RequestMapping(value = "/deletesample/{id}", method = RequestMethod.DELETE)
	public ResponseEntity<Object> deleteSample(@PathVariable(value = "id") Long id) {
		return sampleService.deleteSample(id);
	}

	@RequestMapping(value = "/updatesample/{id}", method = RequestMethod.PUT)
	public SampleEntity updateSample(@PathVariable(value = "id") Long id,
			@Valid @RequestBody SampleEntity sampleEntity) {
		return sampleService.updateSample(id, sampleEntity);
	}

}

In the SampleController class, we have created three new methods such as createSample, deleteSample and updateSample to handle each request separately. We have used two new annotations to handle the requests.

  • @Valid – This annotation is used to validate the entity which is passed a the parameter of the method. As you have seen the usage of @NotNull annotation in the domain model/entity, the @Valid annotation is used to ensure that the values passed to the method contain valid information. This is something similar to a basic form validator.
  • @PathVariable – This annotation is used to pass any values to the URI parameter. In Spring, it is called as URI Template. For example, if you would like to fetch the parameter from the URI as http://localhost:8080/people/ben, where ben is the parameter to be searched for, in the people service, we can use the @PathVariable annotation to fetch that value and pass it to our method.
  • @RequestBody – The @RequestBody annoation is used to denote that the object (in our case, the SampleEntity) which is passed to the method is the body of the request being made.
  • Finally, in the body of each method, we have returned the respective service method from the SampleService class.

Share this:

  • Facebook
  • Twitter
  • WhatsApp
  • Tumblr
  • Google
  • Pinterest