Before Java 16, writing a simple data-carrier class required a constructor, private fields, getters, equals(), hashCode(), and toString() — anywhere from 30 to 60 lines of boilerplate for a handful of fields. Java Records eliminate all of that. A record is a restricted class that is transparently immutable: you declare the fields once, and the compiler generates everything else.
This guide covers every aspect of Java Records you will encounter in a production Spring Boot or Hibernate codebase: declaration syntax, compact constructors, custom accessors, serialisation with Jackson, usage with Hibernate, and the important limitations you need to understand before choosing a record over a plain class.
Generics are the feature that transformed Java from a language of unchecked casts into one of verified type contracts. Introduced in Java 5, they let you write a class or method once and have the compiler enforce type correctness at every call site — without paying a runtime cost. When you write List<Product> instead of List, the compiler catches a misplaced String at compile time rather than surfacing a ClassCastException at 2 a.m. in production. This guide is a complete, runnable reference: generic classes, generic methods, bounded type parameters, wildcards, the PECS rule, and type erasure — with the patterns you will actually reach for in enterprise Java.
This is the companion code post to ← The LLM Gateway Pattern for Java Microservices. That article explains the design decisions behind each layer. This post gives you the complete project — every file, ready to clone and run.
Prerequisites
Java 21+ and Maven 3.9+
Docker and Docker Compose (for Redis)
An OpenAI API key — required. Anthropic and Ollama keys are optional; the gateway falls back automatically if they are absent.
This is the companion code post to ← Production-Grade RAG with Spring AI 1.1.0. That article explains how every layer works. This post gives you the complete project — every file, ready to clone and run.
Prerequisites
Java 21+ and Maven 3.9+
Docker and Docker Compose (for PostgreSQL + pgvector)
Every Java team building AI features eventually faces the same set of problems: a single LLM provider goes down during a critical demo, a runaway loop burns $500 of API credit overnight, or two product teams independently hard-code OpenAI keys into separate microservices and you lose all cost visibility. The LLM Gateway pattern solves all of these — and it’s the most underbuilt component in the Java AI ecosystem today. This post walks through designing and implementing a production-grade LLM Gateway in Spring Boot: multi-provider routing with automatic failover, circuit breaking, rate limiting, cost tracking, semantic caching, and tenant isolation.
Most RAG tutorials stop at “load a PDF, embed it, ask a question.” That works in a demo. In production — handling 10 000 documents, diverse query types, and user expectations of factual accuracy — it falls apart within weeks. This guide walks through every layer of a production-grade Retrieval-Augmented Generation (RAG) system built entirely in Java using Spring AI 1.1.0: from chunking strategy selection and vector store tuning to reranking, hallucination guards, cost tracking, and observability.
Virtual threads shipped as a final feature in Java 21 and matured further in Java 25 (JEP 491 eliminates carrier-thread pinning inside synchronized blocks). The marketing says “millions of threads, almost free” — but what does that actually look like under a stopwatch? In this post we run reproducible benchmarks against platform threads, show where virtual threads win big (and where they don’t), and give you a clear decision table for your own code.