JPA’s EntityManager.getReference() returns an entity reference without requiring an immediate SELECT. When the persistence context already manages the identifier, it returns that instance; otherwise Hibernate creates an uninitialized proxy carrying the identifier. Unlike find(), it does not return null for a missing database row. section 10.2.4 section 12.1.1
Use the reference with these lifecycle and initialization rules:
- Call the mapped identifier getter without necessarily initializing the proxy; calling another method, such as getName(), triggers a SELECT. section 10.2.4 section 12.1.1
- Check initialization with PersistenceUnitUtil.isLoaded() or Hibernate.isInitialized(), and explicitly load data with Hibernate.initialize() while the persistence context remains open. section 10.2.4 section 12.1.1
- Accessing an uninitialized proxy after the persistence context closes causes LazyInitializationException; initializing it beforehand avoids that failure. section 10.2.4
- A missing row is reported as EntityNotFoundException when the proxy initializes, rather than during getReference() itself. section 10.2.4
- Entity classes must support Hibernate proxying: they need a public or protected no-argument constructor and non-final classes and methods. section 12.1.1
Persisting an association without loading either entity
Item item = em.getReference(Item.class, ITEM_ID); User user = em.getReference(User.class, USER_ID); Bid bid = new Bid(new BigDecimal("99.00")); bid.setItem(item); bid.setBidder(user); em.persist(bid); This procedure can issue only the BID INSERT, with no SELECT for the referenced Item or User. section 12.1.1
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.
Follow the executable lifecycle example from proxy creation and isLoaded() verification through persistence-context closure and the resulting lazy-access exception. section 10.2.4
