Step 1: Add JPA and H2 Dependencies
In your pom.xml
, add the following dependencies for Spring Data JPA and the H2 in-memory database:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency>
Step 2: Configure Spring Boot Application Properties
In src/main/resources/application.properties
:
# Enable SQL query logging spring.jpa.show-sql=true # Enable H2 console spring.h2.console.enabled=true spring.h2.console.path=/h2-console
Step 3: Create the JPA Entity
Create Item.java
in the appropriate package. This entity will map to the database table.
import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Transient; @Entity public class Item { @Id private int id; private String name; private int price; private int quantity; @Transient private int value; // Not stored in the DB, used for business logic. // Default constructor needed by JPA protected Item() {} public Item(int id, String name, int price, int quantity) { this.id = id; this.name = name; this.price = price; this.quantity = quantity; } // Getters and setters omitted for brevity (generate them) }
Step 4: Create the Repository Interface
Create an interface extending JpaRepository
:
import org.springframework.data.jpa.repository.JpaRepository; public interface ItemRepository extends JpaRepository<Item, Integer> { // No methods needed; JpaRepository provides CRUD operations. }
Step 5: Create the Business Service
An example service to retrieve all items and add business logic (calculating value = price * quantity
):
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class ItemBusinessService { @Autowired private ItemRepository repository; public List<Item> retrieveAllItems() { List<Item> items = repository.findAll(); for (Item item : items) { item.setValue(item.getPrice() * item.getQuantity()); } return items; } }
Step 6: Create the REST Controller
Expose the business service through a controller:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class ItemController { @Autowired private ItemBusinessService businessService; @GetMapping("/all-items-from-database") public List<Item> retrieveAllItems() { return businessService.retrieveAllItems(); } }
Step 7: Unit Testing the Controller
Since controller depends on the business service, mock the business service and test controller JSON response using Spring Boot test utilities.
Example with Mockito and MockMvc (in ItemControllerTest.java
):
import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; import java.util.Arrays; import java.util.List; import static org.hamcrest.Matchers.hasSize; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @WebMvcTest(ItemController.class) public class ItemControllerTest { @Autowired private MockMvc mockMvc; @MockBean private ItemBusinessService businessService; @Test public void testRetrieveAllItems() throws Exception { List<Item> items = Arrays.asList( new Item(10001, "item1", 10, 20), new Item(10002, "item2", 5, 10) ); // Mock the business service Mockito.when(businessService.retrieveAllItems()).thenReturn(items); mockMvc.perform(get("/all-items-from-database")) .andExpect(status().isOk()) .andExpect(jsonPath("$", hasSize(2))) .andExpect(jsonPath("$[0].name").value("item1")) .andExpect(jsonPath("$[1].name").value("item2")); } }
Step 7: Unit Testing the Business Service
Mock the repository and test business logic:
import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; public class ItemBusinessServiceTest { @Mock private ItemRepository repository; @InjectMocks private ItemBusinessService businessService; public ItemBusinessServiceTest() { MockitoAnnotations.openMocks(this); } @Test public void testRetrieveAllItems() { List<Item> items = Arrays.asList( new Item(10001, "item1", 10, 10), // expected value = 100 new Item(10002, "item2", 20, 20) // expected value = 400 ); when(repository.findAll()).thenReturn(items); List<Item> result = businessService.retrieveAllItems(); assertEquals(100, result.get(0).getValue()); assertEquals(400, result.get(1).getValue()); } }