This project is a comprehensive Library Management System developed using Spring Boot 3, Java 21, and PostgreSQL database. The system allows librarians to manage books, users, and borrowing/returning processes. It also includes user authentication, authorization, API documentation, and testing functionality.
- Technology Stack
- ER Diagram
- Project Structure
- Entities
- API Endpoints
- JWT and Security
- Installation and Running
- Docker Setup
- Test Coverage
- Postman Collection
- Screenshots
- License
-
Backend:
- Spring Boot 3.4.5
- Java 21
- Spring Data JPA
- Spring Security
- Spring Validation
- Spring DevTools
- JWT Authentication (acces + refresh token / role based authentication)
- Swagger/OpenAPI Documentation
-
Database:
- PostgreSQL
- H2 Database (for testing)
-
Build Tool:
- Maven
-
Testing:
- JUnit 5
- Mockito
- Spring Boot Test
- Spring Security Test
- AssertJ
- Jacoco (for test coverage)
-
DevOps:
- Docker & Docker Compose
- Git
-
Other Tools:
- Lombok
- SLF4J/Logback (for logging)
library-management-system/
βββ π src/
β βββ π main/
β β βββ π java/com/getir/aau/librarymanagementsystem/
β β β βββ π config/
β β β βββ π controller/
β β β βββ π exception/
β β β βββ π initializer/
β β β βββ π model/
β β β β βββ π dto/
β β β β βββ π entity/
β β β β βββ π mapper/
β β β βββ π repository/
β β β βββ π security/
β β β β βββ π auth/
β β β β βββ π exception/
β β β β βββ π jwt/
β β β β βββ π token/
β β β β βββ π CustomUserDetailsService.java
β β β β βββ π SecurityUtils.java
β β β βββ π service/
β β β β βββ π impl/
β β β β βββ π AuthorService.java
β β β β βββ π BookService.java
β β β β βββ π BorrowItemService.java
β β β β βββ π BorrowRecordService.java
β β β β βββ π CategoryService.java
β β β β βββ π UserService.java
β β β βββ π LibraryManagementSystemApplication.java
β β βββ π resources/
β β βββ π data/
β β βββ π static/
β β βββ π templates/
β β βββ π application.yml
β β βββ π application-docker.yml
β
β βββ π test/
β βββ π java/com/getir/aau/librarymanagementsystem/
β βββ π integration/
β β βββ π security/
β β βββ π service/
β βββ π unit/
β β βββ π controller/
β β βββ π security/
β β βββ π service/
β βββ π LibraryManagementSystemApplicationTests.java
βββ π docker-compose.yml
βββ π Dockerfile
βββ π pom.xml
βββ π README.md
To ensure scalability, maintainability, and clean structure, this project is built on a layered (multi-tier) architecture, with a strong focus on modern development standards:
- π§ Rich Domain Model is adopted: domain entities encapsulate both data and relevant behavior (e.g., validation, business rules), rather than being just anemic data holders.
- π¦ Record-based DTOs (
recordkeyword in Java 16+) are used for immutable, concise data transport with built-inequals,hashCode, andtoString. - π Builder Pattern is used in entity creation to promote immutability and readability (e.g.,
User,Book). - π§Ό Clean Code principles are followed: meaningful naming, modular structure, low coupling, high cohesion.
- π SOLID Principles are respected:
- Single Responsibility in services and controllers
- Open/Closed via interface-driven design
- Liskov Substitution via proper abstraction
- Interface Segregation and Dependency Inversion via injected services and interfaces
- β Global Exception Handling via
@ControllerAdvicewith custom exceptions:ResourceNotFoundExceptionResourceAlreadyExistsException
- π‘οΈ Validation is enforced using Jakarta Bean Validation annotations (
@Valid,@NotBlank,@Email, etc.) at both controller and DTO levels. - π§ͺ Best Practices were implemented by studying official documentation, industry standards, and open-source architectures.
This results in a robust, maintainable, testable, and production-ready application structure.
Below is the ER Diagram showing the database schema used in the project:
All data is validated using
javax.validationconstraints, ensuring proper format and input integrity. DTOs are implemented as immutable Javarecords, promoting concise, thread-safe, and boilerplate-free code.
Stores author details with unique name and description. Each author can be associated with multiple books via a one-to-many relationship.
Contains book metadata such as title, ISBN, description, genre, publication date, and number of copies. Each book is linked to one author and one category. Borrowing logic is embedded using rich domain methods (borrow, returnBook, updateAvailability).
Defines categories/genres that group books. Each category can be associated with multiple books.
Represents a single item in a user's borrowing transaction. It is related to the User, Book, and BorrowRecord entities.
Each BorrowItem stores the borrow date, due date, return date, and whether it has been returned.
When a book is returned, the markAsReturned() method is called to finalize the return and update the book's availability. This structure is essential for tracking active and overdue loans.
Represents a user's borrowing transaction, which can contain multiple borrowed books (BorrowItem). It includes details such as borrow date and due date, and is linked to the user who initiated the borrowing. Acts as a wrapper to group multiple BorrowItem instances for reporting, tracking, and due management.
Tracks a user's borrowing session. Contains the borrow date, due date, and a list of BorrowItem entries. Establishes a many-to-one relationship with User.
Stores user details such as name, email, password, and phone number. Implements UserDetails for Spring Security integration. Each user is associated with a role and can have multiple borrowings and tokens.
Represents the system users, including login credentials and role information. Can borrow multiple books.
Represents a user's role in the system with a name and description. Connects users to their permissions.
Enumerates the available roles: ROLE_USER, ROLE_LIBRARIAN. Used in the Role entity for Spring Security.
Represents access and refresh tokens assigned to users. Each token has a unique value and is typed as BEARER. Tokens can be revoked or expired. This structure enables multi-session management and helps track the user's active authenticated sessions. Each token is linked to a single user.
The following default users are automatically created for testing purposes:
| Role | Password | |
|---|---|---|
| Librarian | librarian@gmail.com | Password123 |
| User | user@gmail.com | Password123 |
π Note: All default users share the same password: Password123. You can change it after logging in if needed.
- Add Book: Librarians can add books with details like title, author, ISBN, publication date, and genre. Input is validated.
- View Book Details: All authenticated users can view book details.
- Search Books: Users can search books by title, category name, author name, ISBN, or genre. Pagination is supported.
- Update Book: Librarians can update book details.
- Delete Book: Librarians can remove books from the system.
- User Registration: All users can register with the default role: ROLE_USER.
- Role Management: Roles (LIBRARIAN or USER) can be assigned by LIBRARIAN users.
- View User: Librarians can view all users. Users can view their own information.
- Update User: Librarians can update any user. Users can update their own information.
- Delete User: Librarians can remove users from the system.
-
Borrow a Book Users can borrow multiple books in a single transaction. The system checks:
- Whether the user has reached the maximum borrow limit
- Whether the user has overdue items
- Whether the selected books are available
-
Return a Book Librarians and users can mark books as returned. The system:
- Sets the return date
- Automatically updates the book's availability and number of copies
-
Borrow Record Management Librarians can:
- View all borrow records with pagination
- Filter borrow records by user, email, or date range
- Check if a user is eligible to borrow (overdue records and active borrow status)
- Check book availability based on stock and status
-
Borrow Item Insights The system provides:
- All borrow items per user
- Active borrow items and overdue item checks
- Count of active borrow items per user
- Overdue borrow item reports
- Borrow records filtered by book, author, or category
- Borrow statistics by date range
- Every newly registered user is assigned the
ROLE_USERby default. - A librarian must register first, then another librarian can assign them the
ROLE_LIBRARIAN.
-
When a user borrows a book:
- A new
BorrowRecordis created. - Each book is registered as a
BorrowItemunder that record. - Borrow date and due date are automatically calculated.
- A new
-
When a user returns a book:
- Return date is saved.
- The book's copy count and availability are updated.
- The corresponding
BorrowItemandBorrowRecordare marked as returned. - The user's borrow eligibility is recalculated.
This structured flow ensures data integrity and accurate tracking of library operations.
| Method | Endpoint | Description | Access Permission |
|---|---|---|---|
| POST | /api/auth/login |
Authenticate user and get tokens | Public |
| POST | /api/auth/logout |
Logout user (revoke current token) | Public |
| POST | /api/auth/refresh |
Refresh access token using a valid refresh token | Public |
| POST | /api/auth/register |
Register a new user | Public |
| POST | /api/auth/change-password |
Change user password | USER, LIBRARIAN |
| Method | Endpoint | Description | Access Permission |
|---|---|---|---|
| GET | /api/authors |
Get all authors | LIBRARIAN |
| POST | /api/authors |
Create a new author | LIBRARIAN |
| GET | /api/authors/{id} |
Get author by ID | LIBRARIAN |
| PUT | /api/authors/{id} |
Update an existing author | LIBRARIAN |
| DELETE | /api/authors/{id} |
Delete an author | LIBRARIAN |
| Method | Endpoint | Description | Access Permission |
|---|---|---|---|
| POST | /api/books |
Create a new book | LIBRARIAN |
| GET | /api/books/{id} |
Get book by ID | USER, LIBRARIAN |
| PUT | /api/books/{id} |
Update an existing book | LIBRARIAN |
| DELETE | /api/books/{id} |
Delete a book | LIBRARIAN |
| GET | /api/books/author/{authorId} |
Get books by author ID | USER, LIBRARIAN |
| GET | /api/books/author/name |
Get books by author name | USER, LIBRARIAN |
| GET | /api/books/available |
Get available books | USER, LIBRARIAN |
| GET | /api/books/category/{categoryId} |
Get books by category ID | USER, LIBRARIAN |
| GET | /api/books/count/author/{authorId} |
Count books by author ID | USER, LIBRARIAN |
| GET | /api/books/genre |
Get books by genre | USER, LIBRARIAN |
| GET | /api/books/isbn/{isbn} |
Get book by ISBN | USER, LIBRARIAN |
| GET | /api/books/search |
Search books by keyword | USER, LIBRARIAN |
| GET | /api/books/title |
Get books by title | USER, LIBRARIAN |
| GET | /api/books/unavailable |
Get unavailable books | LIBRARIAN |
| Method | Endpoint | Description | Access Permission |
|---|---|---|---|
| PUT | /api/borrow-items/{itemId}/return |
Return a borrowed book | LIBRARIAN |
| GET | /api/borrow-items/book/{bookId} |
Get borrow items by book ID | LIBRARIAN |
| GET | /api/borrow-items/date-range |
Get borrow items by date range | LIBRARIAN |
| GET | /api/borrow-items/overdue |
Get overdue borrow items | LIBRARIAN |
| GET | /api/borrow-items/user/{userId} |
Get borrow items by user ID | USER, LIBRARIAN |
| GET | /api/borrow-items/user/{userId}/active |
Get active borrow items for a user | USER, LIBRARIAN |
| GET | /api/borrow-items/user/{userId}/count-active |
Count active borrow items for a user | USER, LIBRARIAN |
| GET | /api/borrow-items/user/{userId}/exist-overdue |
Check if user has overdue items | USER, LIBRARIAN |
| Method | Endpoint | Description | Access Permission |
|---|---|---|---|
| GET | /api/borrow-records |
Get all borrow records (paginated) | LIBRARIAN |
| POST | /api/borrow-records |
Create a new borrow record | USER, LIBRARIAN |
| GET | /api/borrow-records/{id} |
Get borrow record by ID | USER, LIBRARIAN |
| GET | /api/borrow-records/book-availability/{bookId} |
Check if a book is available for borrowing | LIBRARIAN |
| GET | /api/borrow-records/check-eligibility/{userId} |
Check if user is eligible to borrow books | LIBRARIAN |
| GET | /api/borrow-records/filter |
Filter borrow records by email and date range | LIBRARIAN |
| GET | /api/borrow-records/user/{userId} |
Get borrow records by user ID | USER, LIBRARIAN |
| GET | /api/borrow-records/user/{userId}/active |
Get active borrow records by user ID | USER, LIBRARIAN |
| Method | Endpoint | Description | Access Permission |
|---|---|---|---|
| GET | /api/categories |
Get all categories | LIBRARIAN |
| POST | /api/categories |
Create a new category | LIBRARIAN |
| GET | /api/categories/{id} |
Get category by ID | LIBRARIAN |
| PUT | /api/categories/{id} |
Update an existing category | LIBRARIAN |
| DELETE | /api/categories/{id} |
Delete a category | LIBRARIAN |
| Method | Endpoint | Description | Access Permission |
|---|---|---|---|
| GET | /api/users |
Get all users | LIBRARIAN |
| POST | /api/users |
Create a new user (default role: USER) | LIBRARIAN |
| GET | /api/users/{id} |
Get user by ID | LIBRARIAN |
| PUT | /api/users/{id} |
Update a user | LIBRARIAN |
| DELETE | /api/users/{id} |
Delete a user | LIBRARIAN |
| PUT | /api/users/{id}/role |
Change a user's role | LIBRARIAN |
| GET | /api/users/email |
Get user by email | LIBRARIAN |
| GET | /api/users/me |
Get current user's own information | USER, LIBRARIAN |
Authentication and authorization are implemented using Spring Security and JWT. The system has the following features:
- Endpoints for user registration, login, logout, token refresh, and access control
- Passwords are hashed using BCrypt for security
- Stateless authentication using signed JWTs
- Access tokens expire in 1 day
- Refresh tokens expire in 7 days
- Role-based authorization with two roles: USER and LIBRARIAN
- Change password functionality for users and librarians
- Java 21
- Maven
- PostgreSQL
-
Clone the project:
git clone https://github.com/yourGithubUserName/LibraryManagementSystem.git cd LibraryManagementSystem -
Set up PostgreSQL database: (only required if you're not using Docker or prefer manual setup)
CREATE DATABASE library_db; CREATE USER your_database_user WITH PASSWORD 'your_database_password'; GRANT ALL PRIVILEGES ON DATABASE library_db TO your_database_user;
-
Edit the
application.ymlfile:server: port: 8080 spring: application: name: LibraryManagementSystem datasource: url: jdbc:postgresql://localhost:5432/library_db username: your_database_user password: your_database_password driver-class-name: org.postgresql.Driver application: security: jwt: secret-key: your-secret-key expiration: 86400000 # 1 day refresh-token: expiration: 604800000 # 7 days
-
Build and run the project:
mvn clean package java -jar target/library-management-system-1.0.0.jar
-
The application will run on port 8080: http://localhost:8080
- Docker
- Docker Compose
-
Clone the project:
git clone https://github.com/<your-username>/LibraryManagementSystem.git cd LibraryManagementSystem
-
Build the Docker image and start the services:
docker-compose up -d
-
Access the application: http://localhost:8080/swagger-ui.html
This command:
- Starts a PostgreSQL 16 database in the
library-dbcontainer - Builds the Spring Boot app and runs it in the
library-management-appcontainer - Creates the necessary network and volume configurations automatically
To stop the services:
docker-compose downTo remove all containers and volumes:
docker-compose down -vThis project includes both unit tests and integration tests, comprehensive test coverage for business logic, security, and REST API endpoints.
Tests are performed using the H2 in-memory database.
- JUnit 5: Core testing framework
- Mockito: For mocking dependencies
- AssertJ: For fluent and expressive assertions
- Unit Tests: For individual service and utility methods
- Integration Tests: For verifying controller and service behavior with Spring context
- Security Tests: For testing role-based access and JWT validation
To run all tests:
mvn testJacoco coverage report will be generated at:
target/site/jacoco/index.html
A Postman collection is provided for testing the API endpoints. The collection file can be found at Postman Collection or postman_collection.json in the project's root directory.
- π Authentication: Register, login, logout, refresh token
- π Books: Create, update, delete, search, and list books
- π₯ Users: View, edit, and manage users (by librarians)
- π Borrowing: Borrow, return, and track books
- π Categories and Authors: Full CRUD operations
The collection uses a Postman environment with variables such as:
{{baseUrl}}: API base URL (e.g.,http://localhost:8080){{token}}: JWT access token (auto-filled after login)
A JavaScript snippet is included to automatically save the access token:
pm.environment.set("token", pm.response.json().refresh_token);This project is licensed under the MIT License.


