Java

223 posts in this section

Testing Spring Security: @WithMockUser, MockMvc, and SecurityMockMvc

Why Security Tests Are Non-Negotiable A security configuration that is never tested is a security configuration that is probably wrong. URL patterns have subtle ordering rules. Method security annotations are silently ignored if @EnableMethodSecurity is missing. CSRF tokens must be present in the right form. Testing is the only way to know your authorization rules are actually enforced. Test Dependencies <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> @WithMockUser The simplest way to simulate an authenticated user.

Continue reading »

Text Blocks (JEP 378): Multiline Strings Without the Escape Hell

Finalized in Java 15 (JEP 378). Available in all Java 15+ releases, including Java 17. Previous previews: Java 13 (JEP 355) and Java 14 (JEP 368). The Problem: Embedded Strings in Java Writing multi-line strings in Java has always been painful: // JSON — a wall of escape sequences and concatenation String json = "{\n" + " \"name\": \"Alice\",\n" + " \"role\": \"engineer\",\n" + " \"active\": true\n" + "}"; // SQL — unreadable indentation and newlines String sql = "SELECT u.

Continue reading »

The N+1 Problem: Detection, Root Cause, and All Solutions

What Is the N+1 Problem? The N+1 problem occurs when loading a list of N entities triggers N additional queries to load their associations — one query per entity. Example: load 50 orders, then access each order’s customer: SELECT * FROM orders; -- 1 query SELECT * FROM customers WHERE id = 1; -- query for order 1's customer SELECT * FROM customers WHERE id = 2; -- query for order 2's customer SELECT * FROM customers WHERE id = 3; -- query for order 3's customer .

Continue reading »

The Persistence Context: How JPA Tracks Your Entities

Introduction The persistence context is the single most important concept in JPA. Everything else — lazy loading, dirty checking, transaction scope, detached entity exceptions — only makes sense once you understand what the persistence context is and how it works. Many JPA bugs come from developers not understanding this concept. Understand it well and the rest of JPA becomes predictable. What Is the Persistence Context? The persistence context is an in-memory map of entities managed by the current EntityManager.

Continue reading »

The Security Filter Chain: Every Filter Explained

Every Filter Has a Job The Spring Security filter chain is not a monolith — it’s 15-20 individual filters, each responsible for exactly one concern. Understanding each filter’s job means you can: Know exactly where in the chain a request fails Add your own filter in the right position Remove filters you don’t need for performance Debug authentication and authorization problems The Complete Filter Order Spring Security defines a strict ordering for its filters.

Continue reading »

Tooling: JShell, jlink, and Single-File Programs (JEP 222, 282, 330)

Overview Java 9 and 11 added three tools that change how you write, test, and deploy Java code: Tool JEP Release Purpose JShell JEP 222 Java 9 Interactive REPL for Java code jlink JEP 282 Java 9 Build minimal custom JRE images Single-file programs JEP 330 Java 11 Run .java files directly JShell — Interactive Java REPL JShell is Java’s Read-Eval-Print Loop: a command-line tool for evaluating Java expressions, statements, methods, and classes interactively, without creating a project.

Continue reading »

Transaction Boundaries and Common Pitfalls

Transaction Boundaries A transaction boundary is the point where a transaction starts and where it ends. In Spring, boundaries are defined by @Transactional on service methods. HTTP Request └── Controller (no transaction) └── @Transactional Service method ← transaction OPENS here ├── Repository call 1 ├── Repository call 2 └── method returns ← transaction COMMITS here Everything inside the @Transactional method runs in the same database transaction. The persistence context (first-level cache) lives for the duration of that transaction.

Continue reading »

Unnamed Classes and Instance Main Methods (JEP 445): Java for Scripts and Beginners

Preview Feature — Requires --enable-preview at compile and runtime. The Boilerplate Problem Teaching Java to a beginner means explaining class declarations, access modifiers, static, and String[] before they can print “Hello, World!”: // Traditional Java — 4 concepts before printing one line public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } Every word carries meaning, but that meaning is irrelevant until the student understands OOP, the JVM class model, and program entry points.

Continue reading »

Unnamed Patterns and Variables (JEP 443): Writing Intent-Clear Code

Preview Feature — Requires --enable-preview at compile and runtime. The _ identifier was reserved in Java 9; this JEP gives it formal semantics. The Problem: Forced Naming of Unused Things When pattern matching, you often care about only some components of a matched structure. But the syntax forces you to name everything: record Point(int x, int y) {} record ColoredPoint(Point point, String color) {} record Box(ColoredPoint cp, int weight) {} // You only care about the color — but must name everything else if (obj instanceof Box(ColoredPoint(Point(int x, int y), String color), int weight)) { System.

Continue reading »

var Keyword (JEP 286, 323): Local Variable Type Inference

What var Does var is a reserved type name (not a keyword) introduced in Java 10 (JEP 286). It instructs the compiler to infer the type of a local variable from its initialiser. The inferred type is fixed at compile time — var does not make Java dynamically typed. // Before var ArrayList<String> names = new ArrayList<String>(); Map<String, List<Integer>> scores = new HashMap<String, List<Integer>>(); // With var var names = new ArrayList<String>(); var scores = new HashMap<String, List<Integer>>(); After compilation, both forms produce identical bytecode.

Continue reading »