Eager loading retrieves an entity’s selected associations or collections when the entity is loaded, rather than waiting for code to access them. Use it when those values must remain available after detachment or closure of the persistence context; an uninitialized lazy proxy cannot be loaded then. `FetchType.EAGER` is a requirement to load the data, not a guarantee that Hibernate will use one SQL query. section 12.1.3 section 12.2.5
Load an item with its seller and bids
Map `seller` and `bids` with `fetch = FetchType.EAGER`, then call `em.find(Item.class, ITEM_ID)`. With JOIN fetching, Hibernate can select the item, seller, and bids together. After `em.detach(item)`, both the seller and bids remain accessible. The loaded graph has a boundary: a bidder referenced by a bid may still be an uninitialized proxy and fail on access after detachment. section 12.1.3
Path: Ch12/eagerjoin/src/main/java/com/manning/javapersistence/ch12 /eagerjoin/Item.java @Entity public class Item { @ManyToOne(fetch = FetchType.EAGER) #1 private User seller; @OneToMany(mappedBy = "item", fetch = FetchType.EAGER) #2 private Set<Bid> bids = new HashSet<>(); // . . . } #1 <kbd>FetchType.EAGER</kbd> is the default for entity instances. #2 Generally, <kbd>FetchType.EAGER</kbd> on a collection is not recommended. Unlike <kbd>FetchType.LAZY</kbd>, which is a hint the JPA provider can ignore, <kbd>FetchType.EAGER</kbd> is a hard requirement. The provider has to guarantee that the data is loaded and available in detached state; it can’t ignore the setting.
Compare the eager `@ManyToOne` and `@OneToMany` mappings; the collection setting makes every item load include its bids, even when they are not needed. section 12.1.3
Choose the fetch plan and SQL strategy separately:
- A JOIN for a single-valued association such as `@ManyToOne` or `@OneToOne` can load related rows in one SELECT without multiplying result rows. `hibernate.max_fetch_depth` limits how far Hibernate follows these joins; reaching the limit can introduce additional SELECTs. section 12.2.2
- JOIN-fetching multiple collections can produce a Cartesian product and a large result set with duplicate data. Avoid making collections globally eager merely to prevent later lazy loads. section 12.2.2 section 12.1.3
- Hibernate’s `FetchMode.SELECT` can satisfy an eager mapping with immediate additional SELECTs instead of one large JOIN result. The data is still loaded before `find()` returns, but the extra queries are paid on every applicable load. section 12.2.5
Path: Ch12/eagerselect/src/test/java/com/manning/javapersistence/ch12 /eagerselect/EagerSelect.java Item item = em.find(Item.class, ITEM_ID); #1 // select * from ITEM where ID = ? // select * from USERS where ID = ? // select * from BID where ITEM_ID = ? em.detach(item); assertEquals(3, item.getBids().size()); #2 assertNotNull(item.getBids().iterator().next().getAmount()); #2 assertEquals("johndoe", item.getSeller().getUsername()); #2 #1 Hibernate uses one <kbd>SELECT</kbd> to load a row from the <kbd>ITEM</kbd> table. It then immediately executes two more <kbd>SELECT</kbd>s: one loading a row from the <kbd>USERS</kbd> table (the <kbd>seller</kbd>) and the other loading several rows from the <kbd>BID</kbd> table (the <kbd>bids</kbd>). The additional <kbd>SELECT</kbd> queries aren’t executed lazily; the <kbd>find()</kbd> method produces several SQL queries. #2 Hibernate followed the eager fetch plan; all data is available in detached state.
The three annotated SELECTs make the distinction visible: eager loading describes when the seller and bids become available, while the fetch strategy determines how Hibernate queries them. section 12.2.5
Neither extreme is a general default. Lazy associations can cause too many small queries—the n+1 selects problem—while broad eager plans can load unnecessary data or enlarge JOIN results. Prefer lazy mappings for associations and collections, then request eager fetching for the procedures that need it. Also account for lifecycle operations: with `CascadeType.MERGE`, Hibernate may JOIN-fetch associations during merging even when their mapping says `FetchType.LAZY`. section 12.2 section 12.2.5 section 13.1.2

