Today we'll implement a small but important part of our app: we'll create entities and repositories. We'll extend our project's functionality by adding database support. During the process we'll go step by step through:
- Creating an entity — the core of working with JPA. We'll use annotations like
@Entity,@Id,@GeneratedValueand others. - Configuring repositories. We'll hook up
JpaRepositoryand use its standard methods. - Hands-on CRUD operations. We'll save, update, delete and read data from the database.
1. Task definition
Imagine you're working on a library catalog management system. As a learning example we'll create an entity Book that represents a book, and provide basic operations to interact with it through the database. Our tasks:
- Create an entity
Bookwith fieldsid,title,authorandpublishedYear. - Implement a repository for it.
- Write methods to save and retrieve data.
2. Creating the entity
Let's start by creating the entity class Book. Remember the main rule: entities map to database tables. Each field of our class becomes a column in the table. We'll use annotations @Entity, @Id, @GeneratedValue, @Column for that.
Open the project and add a new class Book in the entity package.
package com.example.library.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Column;
@Entity
public class Book {
@Id // Specify the primary key
@GeneratedValue(strategy = GenerationType.IDENTITY) // Automatic ID generation
private Long id;
@Column(nullable = false) // Field is required
private String title;
@Column(nullable = false)
private String author;
@Column(name = "published_year") // Specify the column name in the database
private Integer publishedYear;
// Constructors, getters, setters
public Book() {
}
public Book(String title, String author, Integer publishedYear) {
this.title = title;
this.author = author;
this.publishedYear = publishedYear;
}
// Getters and setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Integer getPublishedYear() {
return publishedYear;
}
public void setPublishedYear(Integer publishedYear) {
this.publishedYear = publishedYear;
}
}
In the code:
@Entity— marks the class as an entity that will be mapped to a database table.@Id— the field that will be used as the table's primary key.@GeneratedValue(strategy = GenerationType.IDENTITY)— automatic ID generation for new records.@Column— column configuration; we addednullable = falseto make the field required.
Now that our entity is ready, let's move on to the next step!
3. Creating the repository
The repository handles database operations. In Spring Data JPA that's done with interfaces like JpaRepository. We'll create an interface BookRepository and pull in the standard methods.
Add a new interface in the repository package.
package com.example.library.repository;
import com.example.library.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
// You can add custom methods here if needed
}
JpaRepository<Book, Long>— theBooktype points to our entity, andLongis the type of its identifier.- The
@Repositoryannotation tells Spring this is a component for database access.
Built-in methods from JpaRepository
By extending JpaRepository we get methods such as:
save()— to save an object.findById()— to find an object by ID.findAll()— to get a list of all objects.deleteById()— to delete an object by ID.
4. Hands-on: CRUD operations
Now we'll test the entities and repositories we created. We'll add a basic service and insert some test data.
Add a new service in the service package.
package com.example.library.service;
import com.example.library.entity.Book;
import com.example.library.repository.BookRepository;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class BookService {
private final BookRepository bookRepository;
public BookService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
// Adding a book
public Book addBook(Book book) {
return bookRepository.save(book);
}
// Getting all books
public List<Book> getAllBooks() {
return bookRepository.findAll();
}
// Finding a book by ID
public Optional<Book> getBookById(Long id) {
return bookRepository.findById(id);
}
// Deleting a book by ID
public void deleteBook(Long id) {
bookRepository.deleteById(id);
}
}
Now add a controller to test the functionality via HTTP requests.
package com.example.library.controller;
import com.example.library.entity.Book;
import com.example.library.service.BookService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/books")
public class BookController {
private final BookService bookService;
public BookController(BookService bookService) {
this.bookService = bookService;
}
@PostMapping
public Book addBook(@RequestBody Book book) {
return bookService.addBook(book);
}
@GetMapping
public List<Book> getAllBooks() {
return bookService.getAllBooks();
}
@GetMapping("/{id}")
public Book getBookById(@PathVariable Long id) {
return bookService.getBookById(id).orElseThrow(() -> new RuntimeException("Book not found"));
}
@DeleteMapping("/{id}")
public void deleteBook(@PathVariable Long id) {
bookService.deleteBook(id);
}
}
To test, you can send requests using Postman or a similar tool.
5. Run and verify
- Run the application on your local server.
- Check the database to make sure the
booktable was created. - Use these requests:
POST /bookswith body:{ "title": "Spring in Action", "author": "Craig Walls", "publishedYear": 2021 }GET /books— to get all books.GET /books/{id}— to get a book by ID.DELETE /books/{id}— to delete a book.
Congrats! You created your first entity and hooked it up to the database with minimal effort! Now your code is closer to real production!
GO TO FULL VERSION