A high-performance, thread-safe backend system for managing industrial equipment rentals. Designed as a Final Capstone Project to demonstrate mastery of Raw JDBC, Explicit Concurrency Control, and Financial Precision without reliance on heavy frameworks like Hibernate or Spring Data.
Status: v1.0.0 (Gold Release)
Type: Console-based Enterprise Application (CLI)
This system solves the "Object-Relational Impedance Mismatch" manually, implementing patterns like Data Mapper, Unit of Work (via Transaction Scripts), and Class Table Inheritance from scratch. It guarantees data integrity through database-level constraints and robust Java domain logic.
- Atomic Cart System: Implements an "All-or-Nothing" transactional model. If a single item in the cart is unavailable, the entire contract creation rolls back to ensure data consistency.
- Smart Availability: Powered by PostgreSQL Exclusion Constraints (
EXCLUDE USING GIST), physically preventing overlapping rental periods at the database level. - Time-Based Booking: Supports future reservations even for currently rented equipment (Hotel-style availability).
- Polymorphic Inventory: Manages diverse assets using Class Table Inheritance (CTI). Distinct logic for
HeavyMachinery(engine hours, fuel) vs.PortableTools(consumables, power source). - Customer Segmentation: Differentiates between
IndividualandCompanyclients (via STI), supporting VIP Tiers with automatic discount application.
- High-Precision Math: All calculations use
BigDecimal(Scale 2) to prevent IEEE 754 floating-point errors. - Dynamic Penalty Strategies:
- Late Returns:
(Days Late * Daily Rate * 1.5). - Heavy Usage:
(Excess Engine Hours * Hourly Rate * 1.5)calculated dynamically based on machine specifications.
- Late Returns:
- Revenue Recognition: A double-entry ledger system separating Accrued Rent (Linear recognition over time) from Penalties (Point-in-Time recognition upon return).
- RBAC Security: Role-Based Access Control enforcing strict permissions for ADMIN (full access), MANAGER (operational access), and INTERN (read-only).
- Immutable Audit Trail: Automatically logs all critical operations (Create, Update, Rent, Return) with actor IDs and timestamps into a secured
audit_logstable. - Condition Checks: Input loops validate return conditions, preventing logical errors like "rolling back" engine hour meters.
- Hierarchical Views: Visualizes
Contract -> Items -> Equipmentrelationships using custom ASCII tree renderers. - Display Modes: Supports Compact, Full, and Ledger viewing modes for invoices and history.
- History Dashboard: Provides a consolidated view of active and closed contracts per customer.
| Constraint | Implementation | Rationale |
|---|---|---|
| Zero-ORM | Raw JDBC + Mappers | Full control over SQL execution plans; avoids N+1 problems. |
| Availability | EXCLUDE USING GIST |
Database-level guarantee against double-booking. |
| Concurrency | Optimistic Locking | Uses a version column to prevent lost updates. |
| Precision | BigDecimal (Scale 2) |
Prevents floating-point errors in financial calculations. |
- Language: Java 17 (Records, Text Blocks, Pattern Matching for
instanceof). - Database: PostgreSQL 14+ (Required for
daterangetypes). - Persistence: JDBC (Java Database Connectivity).
- Connection Pooling: HikariCP.
- Testing: JUnit 5 + Testcontainers (Dockerized integration tests).
- Build Tool: Maven.
- Java 17+ installed.
- PostgreSQL 14+ running locally (or via Docker).
- Maven installed.
The application manages its own schema via SQL scripts in src/main/resources/db/migration/.
- Production: Ensure scripts
V1throughV6are executed in order (Flyway or manual execution). - Local Config: Ensure
application-local.propertiesexists insrc/main/resources/with your local DB credentials if they differ from defaults:
db.url=jdbc:postgresql://localhost:5432/rental_db
db.username=postgres
db.password=your_password
# Clean and package the application (skipping tests for speed)
mvn clean package -DskipTests
# Run the JAR file
java -jar target/enterprise-rental-system-1.0-SNAPSHOT.jar
The project is organized into strictly defined layers to enforce Separation of Concerns.
src/main/java/com/rental/
├── domain/ # 🧠 Rich Domain Model (Core Business Logic)
│ ├── inventory/ # Equipment, HeavyMachinery, Portable Tool (CTI Entities)
│ ├── rental/ # Contract, ContractItem, Cart (Aggregates)
│ ├── customer/ # Customer Entities
│ ├── pricing/ # Pricing Policies & Penalty Strategies
│ └── security/ # Authentication & Authorization
│
├── service/ # ⚙️ Application Layer (Transaction Scripts)
│ ├── RentalService.java # Transaction Script (Main Logic)
│ ├── EquipmentService.java # Inventory Lookup
│ ├── CustomerService.java # Customer Lookup
│ └── policy/ # Strategy Pattern for Penalties
│ ├── PenaltyPolicy.java # Interface for penalty calculation
│ ├── LateReturnPolicy.java # Calculates overdue penalties
│ └── HeavyUsagePolicy.java # Calculates engine-hour overage fees
│
├── persistence/mappers/ # 💾 Data Access Layer (Manual ORM)
│ ├── ContractMapper.java # Complex Joins & Locking
│ ├── EquipmentMapper.java # CTI Mapping
│ ├── CustomerMapper.java # Customer Data Access
│ ├── RevenueMapper.java # Financial Log
│ ├── AuditMapper.java # Audit Log
│ └── UserMapper.java # Security Users
│
└── ui/ # 🖥 Presentation Layer (CLI)
├── Main.java # Dependency Injection (Manual Wiring)
├── FrontController.java # CLI State Machine & Validation
└── renderer/ # View Helpers (ASCII Visuals)
├── ContractReportRenderer.java # Generates Invoices & Tables
└── CustomerHistoryRenderer.java # Visualizes Rental Trees
The project relies on Integration Testing using Testcontainers to ensure SQL queries work against a real PostgreSQL instance.
# Run all tests (requires Docker Desktop running)
mvn test
Note: Ensure Docker is running before executing tests, as Testcontainers will spin up a temporary PostgreSQL container.
If integration tests fail with "Could not start container":
- Ensure Docker Desktop is running.
- Enable "Expose daemon on tcp://localhost:2375 without TLS" in Docker settings.
- Set Environment Variable:
DOCKER_HOST=tcp://localhost:2375. - Or export DOCKER_HOST=unix:///var/run/docker.sock (Linux/Mac).
If you see strange characters (e.g., ✅, ??) instead of icons in the console:
- Enable UTF-8 in PowerShell:
Run this command before starting the application:
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
- Run with Encoding Flag:
Launch the JAR with the UTF-8 flag enforced:
java -Dfile.encoding=UTF-8 -jar target/enterprise-rental-system-1.0-SNAPSHOT.jar