Card 01/ 06

ConceptDifficulty: Intermediate1 min

The Query That Multiplies Itself

One method call. One findAll(). Twenty rides, each with a driver loaded lazily. Twenty-one queries actually reach the database.

java
@Transactional(readOnly = true)
List<String> driverNamesForEveryRide() {
    List<Ride> rides = rideRepo.findAll();          // query #1
    return rides.stream()
        .map(r -> r.getDriver().getName())          // one more query, per ride
        .toList();
}
text
20 rides, 1 findAll() call, total prepared statements executed: 21
run in a container, real Hibernate statistics — not estimated

This is the N+1 query pattern: one query to fetch a list, then N more — one per row — to fetch something lazily loaded off each item in it. It's invisible in the code, because nothing about r.getDriver().getName() looks like a database call. It's exactly what lazy loading was covered doing in jdbc-vs-jpa, just now costing twenty round trips instead of failing outright.