Anıl Şenocak Anıl Şenocak
Yazılım Mühendisi
Cover image
2026-07-11 0 toplam yorum
Spring Data File Repository: Local JSON Storage in Spring Boot

This project demonstrates how to implement a lightweight, thread-safe, and local JSON file-based data store directly inside a Spring Boot application, maintaining the standard repository pattern design.

🎯 The Problem: Infrastructure Overhead for Lightweight Services

When developing standalone microservices, tools, or fast prototypes, spinning up a heavy relational database or managing external Docker containers just to persist a few records introduces unwanted friction.

We need a persistent data store that is:

  • 🪶 Zero-dependency: No external database engines required.
  • 📦 Self-contained: Data stored directly inside the project directory footprint.
  • Fast & Lightweight: In-memory operational speeds with instant auto-commit to disk.

⚙️ Core Logic

The Spring Data File Repository abstracts file persistence in a way similar to Spring Data JPA, but instead of database tables, it works with file storage backends (local disk, S3-compatible storage, or custom implementations).

Repository Abstraction (Spring-Data Style)

You define repositories like:

@Repository  
public interface ParkRepository extends JsonRepository<Park, Long> {  
    List<Park> findAll();  
    Page<Park> findAllByOrderByParkIDAsc(Pageable pageable);  
    Page<Park> findAllByParkNameContaining(String parkName, Pageable pageable);  
}

Core operations:

  • save(file)
  • saveAll(files)
  • findById(id)
  • existsById(id)
  • findAll()
  • findAllById(id)
  • count()
  • deleteById(id)
  • delete(file)
  • deleteAllById(id)
  • deleteAll(files)

Also the great feature that comes from Spring Data which is derived methods that examples shown above. Internally, these behave like Spring Data repositories but delegate to storage adapters.

🛠️ The Solution: A Generic, Thread-Safe File Repository

This library provides a fully functional, generic repository pattern backed by local JSON file storage. It leverages Jackson for high-performance serialization, thread-safe memory caches for lookups, and explicit file-level locking mechanisms to prevent corruption.

✨ Key Features

  • 📂 JSON File Persistence: Stores entities cleanly as JSON arrays on disk.
  • 🔄 Full CRUD Implementation: Standard Create, Read, Update, and Delete operations.
  • 🔒 Thread-Safe Architecture: Uses explicit concurrent read-write locks for file access.
  • 💾 Auto-Save Mechanism: Automatically synchronizes in-memory changes to files.
  • 🌐 REST API & Best Practices: Complete demonstration featuring clean Dependency Injection, Global Exception Handling, and SLF4J logging.
  • 🧪 Comprehensive Tests: Includes complete integration test coverage.

📐 Deep Dive: How It Works Under the Hood

[ Client / Controller ]
│  
▼  
[ Service Layer ] (Validation / Business Rules)
│  
▼  
[ Repository Layer] ──▶ [ In-Memory Cache (CopyOnWriteArrayList)]
│  
▼  
[ JsonFileStore]  ──▶ [ ReadWriteLock Protection ] ──▶ [ Local .json File ]

⚙️ JsonFileStore (Core Utility)

  • Concurrent Safety: Uses a ReadWriteLock to ensure multiple threads can read simultaneously, while exclusive access is guaranteed during a write phase.
  • Jackson Mapping: Utilizes Jackson’s ObjectMapper for robust type-safe serialization/deserialization.
  • Resilient I/O: Automatically initializes and constructs the underlying storage directories and target files safely if they do not exist.

🗄️ Repository Layer

  • Fast Reads: Maintains an internal thread-safe CopyOnWriteArrayList acting as a lightning-fast in-memory cache layer.
  • Lazy Initialization: Reads data from disk into memory exactly once during application startup via @PostConstruct.
  • Sync-on-Write: Commits data mutations back to the file array instantly after each transactional repository method.

Configuration

Externalizing parameters is essential. Define your application storage path easily inside your src/main/resources/application.yml:

spring:  
  data:  
    json:  
      file-path: ${user.dir}/example/data

🚀 Adding New Entities & Data Structures

The system natively supports multiple entity structures. The repository directory contains pre-configured implementations for both User and Product models. To add your own custom entity; Define your model class in the model/package. Build a repository extending the generic file store pattern. Expose your business requirements through your service and controller layer.

JSON files are stored in the data/ directory:

  • data/users.json - User data
  • data/products.json - Product data (if used)

Adding New Entities

To add a new entity (e.g., Note, Product):

  1. Create the model class in model/ package
  2. Create a repository class in repository/ package (similar to UserRepository)
  3. Create a service class in service/ package (optional)
  4. Create a controller class in controller/ package (optional)

Example: The Product entity is already included as a reference implementation.

Best Practices Implemented

  • ✅ Dependency Injection via constructor
  • ✅ Configuration properties externalized
  • ✅ Global exception handling
  • ✅ Proper logging with SLF4J
  • ✅ RESTful API design
  • ✅ Separation of concerns (Controller → Service → Repository)
  • ✅ Thread-safe operations
  • ✅ Comprehensive error handling
  • ✅ Integration tests

⚠️ Architectural Limitations

  • Not for Production: While this approach provides a friction-free experience for localized setups, keep these trade-offs in mind before planning your production architecture.
  • Scalability: Queries utilize linear search through the in-memory array list (O(N)). Large datasets will increase look-up times.
  • Concurrent Writes: No Multi-Instance Horizontal Scaling; If multiple separate application instances attempt to read/write to the exact same file pathway simultaneously without a shared file system lock, conflicts will occur.
  • Query Performance: Linear search through in-memory list
  • No Transactions: There are no transaction rollback capabilities stretching across multiple distinct entity alterations.

GitHub - senocak/Spring-Data-File-Repository

Happy coding!

Yorumlar
Henüz yorum yok. İlk yorumu sen yaz.
Yorum Bırak
Adınız (isteğe bağlı)
Yorumunuzu yazın...
0/500