LazyInitializationException occurs when Hibernate tries to load an uninitialized proxy after its persistence context has closed. A proxy carries an entity identifier but cannot fetch the remaining state without an active persistence context. Identifier getters such as getId() can still work because they do not require initialization. section 10.2.4 section 12.1.1
Accessing a detached proxy
Item item = em.getReference(Item.class, ITEM_ID);\nassertFalse(emf.getPersistenceUnitUtil().isLoaded(item));\nem.getTransaction().commit();\nem.close();\nassertThrows(LazyInitializationException.class, () -> item.getName());\n\nInitialize the proxy before closing the persistence context with Hibernate.initialize(item), or load the required association through an appropriate fetch plan. section 10.2.4
Prevent the exception by deciding which state must remain available after detachment:
- Initialize required entities or associations while the persistence context remains open; Hibernate.initialize(item.getSeller()) explicitly loads the seller. section 12.1.1
- Use FetchType.EAGER when a particular association must always be available in detached state, such as an Item seller. section 12.1.3
- Keep collections lazy by default: eager collection loading can load unnecessary rows and create Cartesian-product problems when several collections are fetched together. section 12.1.3
- Remember that lazy loading stops at the persistence-context boundary; loading an Item does not automatically initialize its lazy seller or nested bidder proxies. section 12.1.1 section 12.1.3
Path: managing-data/src/test/java/com/manning/javapersistence/ch10 /SimpleTransitionsTest.java – retrievePersistentReference() Item item = em.getReference(Item.class, ITEM_ID); #1 PersistenceUnitUtil persistenceUtil = #2 emf.getPersistenceUnitUtil(); assertFalse(persistenceUtil.isLoaded(item)); #3 // assertEquals("Some Item", item.getName()); #4 // Hibernate.initialize(item); #5 em.getTransaction().commit(); em.close(); #6 assertThrows(LazyInitializationException.class, () -> item.getName()); #7 #1 The persistence context. #2 The helper methods. #3 Detecting an uninitialized proxy. #4 Mapping the exception to the rule. #5 Load the proxy data. #6 <kbd>item</kbd> is in a detached state. #7 Load data after closing the persistence context.
Trace the complete failure case from an uninitialized getReference() proxy through persistence-context closure to the thrown exception, with optional initialization points. section 10.2.4
