liveBook · Manning

Fetch plan

As explained in Java Persistence with Spring Data and Hibernate epub

A fetch plan is a specification of which entity associations and collections are retrieved, and when they are retrieved, during an operation.

A fetch plan specifies which entity associations and collections are loaded during a retrieval operation or later navigation. In JPA, mapping-level FetchType.LAZY and FetchType.EAGER settings establish a global default. A practical starting point is to map associations and collections lazily, then load more for operations that need it. section 12.1 section 12.4

The plan answers what to load; the fetch strategy answers how to load it. Lazy navigation can issue one SELECT for the initial items and another for each item's seller or bids collection—the n+1 selects problem. Eager loading may reduce query count but produce oversized results, particularly when several collections are joined. Choose overrides for the access pattern rather than making every collection eager. section 12.2 section 12.2.1

Ways to tailor a default plan include:

  • Mapping-level FetchType.EAGER when an association must always be available, including after detachment. Once the persistence context is closed, an uninitialized lazy association cannot be loaded. section 12.1.3
  • JPA entity graphs for a particular find() or query. A load graph treats listed attributes as eager and leaves unlisted attributes at their mapped defaults; named graphs and subgraphs can express reusable paths. Graphs control what loads, not how. section 12.3.2 section 12.3
  • Hibernate fetch profiles for selectively overriding lazy mappings with JOIN eager fetching during a unit of work, or batch and subselect prefetching to reduce queries while retaining lazy mappings. section 12.3 section 12.2.4

Load sellers for an item list

Suppose an item-list operation reads every seller's username. With lazy seller mappings, selecting all items and then calling item.getSeller().getUsername() in a loop can trigger a SELECT per seller. An entity graph naming seller can instead be supplied as the javax.persistence.loadgraph hint; the illustrated query retrieves items and sellers together. Leave bids lazy if the operation never reads them. section 12.2.1 section 12.3.2

Path: Ch12/fetchloadgraph/src/test/java/com/manning/javapersistence/ch12
 /fetchloadgraph/FetchLoadGraph.java
 
Map<String, Object> properties = new HashMap<>();
properties.put(
    "javax.persistence.loadgraph",
    em.getEntityGraph("ItemSeller")
);
Item item = em.find(Item.class, ITEM_ID, properties);
// select i.*, u.*
//  from ITEM i
//   inner join USERS u on u.ID = i.SELLER_ID
// where i.ID = ?

The named ItemSeller load graph is passed to find(); the accompanying SQL shows the seller joined to the requested item. section 12.3.2

How Java Persistence with Spring Data and Hibernate epub covers it

How deep it goes
Works through mapping defaults, detached access, SQL tradeoffs, and entity-graph overrides while distinguishing data selection from fetch strategy.
Examples
Uses item–seller and item–bids mappings, repeated SELECTs during iteration, and a named entity graph applied to find().
What it assumes
Assumes basic Jakarta Persistence retrieval by identifier while keeping JPQL and CriteriaQuery examples simple.
What you can do after
Apply it via JPA mappings and entity graphs to load needed relationships while checking query counts and detached-state requirements.
How it connects
Connects lazy and eager loading with entity graphs, fetch profiles, persistence contexts, n+1 selects, and Cartesian products.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Java Persistence with Spring Data and Hibernate epub. The section links point to the parts of the book it draws on.