Search⌘ K
AI Features

Solution: Book Loan System

Explore how to implement a book loan system with Spring Data JPA by updating entity classes, creating repositories, and managing book loans and returns using transactional methods. Understand entity mappings, auditing annotations, and repository queries to handle availability and loan status effectively.

Solution

Let’s discuss the solution for implementing a book loan system.

Update the Book class

First, we add the available Boolean property to the Book class.

Java
package com.smartdiscover.entity;
import jakarta.persistence.*;
import lombok.Data;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@Data
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String summary;
private Boolean available;
@CreatedBy
private String createdBy;
@CreatedDate
private Date createdDate;
@LastModifiedBy
private String lastModifiedBy;
@LastModifiedDate
private Date lastModifiedDate;
@ManyToMany
@JoinTable(
name = "book_authors",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "author_id"))
private List<Author> authors;
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", summary='" + summary + '\'' +
", authors='" + (null != authors && authors.size() > 0 ? (authors.stream().map(i -> i.getFullName()).collect(Collectors.toList())) : "[]") + '\'' +
", createdBy='" + createdBy + '\'' +
", createdDate='" + createdDate + '\'' +
", lastModifiedBy='" + lastModifiedBy + '\'' +
", lastModifiedDate='" + lastModifiedDate + '\'' +
'}';
}
}

Update the BookRepository interface

Then, we add the findByNameAndAvailableIsNullOrAvailableIsTrue method in the BookRepository interface to search a book by matching the name and its availability as Null or True.

Java
package com.smartdiscover.repository;
import com.smartdiscover.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, Long> {
Book findByNameAndAvailableIsNullOrAvailableIsTrue(String name);
Book findFirstBySummaryIsLikeOrderByNameAsc(String summary);
}

Create the BookLoanEntry class

Then, we create the BookLoanEntry class in the com.smartdiscover.entity package.

Java
package com.smartdiscover.entity;
import jakarta.persistence.*;
import lombok.Data;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.util.Date;
@Data
@Entity
@EntityListeners(AuditingEntityListener.class)
public class BookLoanEntry {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String userFirstName;
private String userLastName;
@ManyToOne
private Book book;
private Date loanDate;
private Date dueDate;
private Date returnDate;
private String status;
@CreatedBy
private String createdBy;
@CreatedDate
private Date createdDate;
@LastModifiedBy
private String lastModifiedBy;
@LastModifiedDate
private Date lastModifiedDate;
}
...