1515import  org .hibernate .cache .spi .access .SoftLock ;
1616import  org .hibernate .engine .internal .Cascade ;
1717import  org .hibernate .engine .internal .CascadePoint ;
18+ import  org .hibernate .engine .spi .ActionQueue ;
1819import  org .hibernate .engine .spi .CascadingActions ;
1920import  org .hibernate .engine .spi .EntityEntry ;
2021import  org .hibernate .engine .spi .PersistenceContext ;
@@ -62,41 +63,7 @@ public void onRefresh(RefreshEvent event, RefreshContext refreshedAlready) {
6263		final  PersistenceContext  persistenceContext  = source .getPersistenceContextInternal ();
6364		final  Object  object  = event .getObject ();
6465		if  ( persistenceContext .reassociateIfUninitializedProxy ( object  ) ) {
65- 			final  boolean  isTransient  = isTransient ( event , source , object  );
66- 			// If refreshAlready is not empty then the refresh is the result of a 
67- 			// cascade refresh and the refresh of the parent will take care of initializing the lazy 
68- 			// entity and setting the correct lock on it, this is needed only when the refresh is called directly on a lazy entity 
69- 			if  ( refreshedAlready .isEmpty () ) {
70- 				final  LazyInitializer  lazyInitializer  = extractLazyInitializer ( object  );
71- 				final  EntityPersister  persister ;
72- 				if  ( lazyInitializer  != null  ) {
73- 					persister  = source .getEntityPersister ( lazyInitializer .getEntityName (), object  );
74- 				}
75- 				else  if  ( !isTransient  ) {
76- 					persister  = persistenceContext .getEntry ( object  ).getPersister ();
77- 				}
78- 				else  {
79- 					persister  = source .getEntityPersister ( source .guessEntityName ( object  ), object  );
80- 				}
81- 
82- 				refresh (
83- 						event ,
84- 						null ,
85- 						source ,
86- 						persister ,
87- 						lazyInitializer ,
88- 						null ,
89- 						persister .getIdentifier ( object , event .getSession () ),
90- 						persistenceContext 
91- 				);
92- 				if  ( lazyInitializer  != null  ) {
93- 					refreshedAlready .add ( lazyInitializer .getImplementation () );
94- 				}
95- 			}
96- 
97- 			if  ( isTransient  ) {
98- 				source .setReadOnly ( object , source .isDefaultReadOnly () );
99- 			}
66+ 			handleUninitializedProxy ( event , refreshedAlready , source , object , persistenceContext  );
10067		}
10168		else  {
10269			final  Object  entity  = persistenceContext .unproxyAndReassociate ( object  );
@@ -109,9 +76,58 @@ else if ( !isTransient ) {
10976		}
11077	}
11178
79+ 	private  static  void  handleUninitializedProxy (
80+ 			RefreshEvent  event ,
81+ 			RefreshContext  refreshedAlready ,
82+ 			EventSource  source ,
83+ 			Object  object ,
84+ 			PersistenceContext  persistenceContext ) {
85+ 		final  boolean  isTransient  = isTransient ( event , source , object  );
86+ 		// If refreshAlready is nonempty then the refresh is the result of a cascade refresh and the 
87+ 		// refresh of the parent will take care of initializing the lazy entity and setting the 
88+ 		// correct lock. This is needed only when the refresh is called directly on a lazy entity. 
89+ 		if  ( refreshedAlready .isEmpty () ) {
90+ 			final  LazyInitializer  lazyInitializer  = extractLazyInitializer ( object  );
91+ 			final  EntityPersister  persister  = getPersister ( lazyInitializer , source , object , isTransient  );
92+ 			refresh (
93+ 					event ,
94+ 					null ,
95+ 					source ,
96+ 					persister ,
97+ 					lazyInitializer ,
98+ 					null ,
99+ 					persister .getIdentifier ( object , event .getSession () ),
100+ 					persistenceContext 
101+ 			);
102+ 			if  ( lazyInitializer  != null  ) {
103+ 				refreshedAlready .add ( lazyInitializer .getImplementation () );
104+ 			}
105+ 		}
106+ 
107+ 		if  ( isTransient  ) {
108+ 			source .setReadOnly ( object , source .isDefaultReadOnly () );
109+ 		}
110+ 	}
111+ 
112+ 	private  static  EntityPersister  getPersister (
113+ 			LazyInitializer  lazyInitializer ,
114+ 			EventSource  source ,
115+ 			Object  object ,
116+ 			boolean  isTransient ) {
117+ 		if  ( lazyInitializer  != null  ) {
118+ 			return  source .getEntityPersister ( lazyInitializer .getEntityName (), object  );
119+ 		}
120+ 		else  if  ( isTransient  ) {
121+ 			return  source .getEntityPersister ( source .guessEntityName ( object  ), object  );
122+ 		}
123+ 		else  {
124+ 			return  source .getPersistenceContextInternal ().getEntry ( object  ).getPersister ();
125+ 		}
126+ 	}
127+ 
112128	private  static  boolean  isTransient (RefreshEvent  event , EventSource  source , Object  object ) {
113129		final  String  entityName  = event .getEntityName ();
114- 		return  entityName  !=  null  ? !source .contains ( entityName ,  object ) : !source .contains (object );
130+ 		return  entityName  ==  null  ? !source .contains ( object   ) : !source .contains (  entityName ,  object   );
115131	}
116132
117133	private  static  void  refresh (RefreshEvent  event , RefreshContext  refreshedAlready , Object  object ) {
@@ -179,25 +195,26 @@ private static void refresh(
179195			Object  object ,
180196			EventSource  source ,
181197			EntityPersister  persister ,
182- 			LazyInitializer  lazyInitializer ,
198+ 			LazyInitializer  initializer ,
183199			EntityEntry  entry ,
184200			Object  id ,
185- 			PersistenceContext  persistenceContext ) {
201+ 			PersistenceContext  context ) {
186202		if  ( object  != null  ) {
187203			final  var  instrumentationMetadata  = persister .getBytecodeEnhancementMetadata ();
188204			if  ( instrumentationMetadata .isEnhancedForLazyLoading () ) {
189205				final  var  interceptor  = instrumentationMetadata .extractInterceptor ( object  );
190206				if  ( interceptor  != null  ) {
191- 					// The list of initialized lazy fields have to be cleared in order to refresh them from the database. 
207+ 					// The list of initialized lazy fields has to be cleared 
208+ 					// before refreshing them from the database. 
192209					interceptor .clearInitializedLazyFields ();
193210				}
194211			}
195212		}
196213
197- 		final  Object  result  =  source . getLoadQueryInfluencers (). fromInternalFetchProfile ( 
198- 				CascadingFetchProfile . REFRESH , 
199- 				() ->  doRefresh (  event ,  source ,  object ,  entry ,  persister ,  lazyInitializer ,  id ,  persistenceContext  ) 
200- 		);
214+ 		final  Object  result  =
215+ 				source . getLoadQueryInfluencers () 
216+ 						. fromInternalFetchProfile (  CascadingFetchProfile . REFRESH , 
217+ 								() ->  doRefresh (  event ,  source ,  object ,  entry ,  persister ,  initializer ,  id ,  context  )  );
201218		UnresolvableObjectException .throwIfNull ( result , id , persister .getEntityName () );
202219	}
203220
@@ -241,7 +258,7 @@ private static Object doRefresh(
241258			if  ( currentLockMode .greaterThan ( requestedLockMode  ) ) {
242259				// the requested lock-mode is less restrictive than the current one 
243260				//		- pass along the current lock-mode (after accounting for WRITE) 
244- 				lockOptionsToUse  = event . getLockOptions () .makeCopy ();
261+ 				lockOptionsToUse  = lockOptionsToUse .makeCopy ();
245262				if  ( currentLockMode  == LockMode .WRITE 
246263						|| currentLockMode  == LockMode .PESSIMISTIC_WRITE 
247264						|| currentLockMode  == LockMode .PESSIMISTIC_READ  ) {
@@ -272,7 +289,7 @@ private static Object doRefresh(
272289
273290		final  Object  result  = persister .load ( id , object , lockOptionsToUse , source  );
274291		if  ( result  != null  ) {
275- 			// apply ` postRefreshLockMode` , if needed 
292+ 			// apply postRefreshLockMode, if needed 
276293			if  ( postRefreshLockMode  != null  ) {
277294				// if we get here, there was a previous entry, and we need to reset its lock mode 
278295				//		- however, the refresh operation actually creates a new entry, so get it 
@@ -312,6 +329,7 @@ private static void evictCachedCollections(EntityPersister persister, Object id,
312329	private  static  void  evictCachedCollections (Type [] types , Object  id , EventSource  source )
313330			throws  HibernateException  {
314331		final  SessionFactoryImplementor  factory  = source .getFactory ();
332+ 		final  ActionQueue  actionQueue  = source .getActionQueue ();
315333		final  MappingMetamodelImplementor  metamodel  = factory .getMappingMetamodel ();
316334		for  ( Type  type  : types  ) {
317335			if  ( type  instanceof  CollectionType  collectionType  ) {
@@ -327,7 +345,7 @@ private static void evictCachedCollections(Type[] types, Object id, EventSource
327345					);
328346					final  SoftLock  lock  = cache .lockItem ( source , ck , null  );
329347					cache .remove ( source , ck  );
330- 					source . getActionQueue () .registerProcess ( (success , session ) -> cache .unlockItem ( session , ck , lock  ) );
348+ 					actionQueue .registerProcess ( (success , session ) -> cache .unlockItem ( session , ck , lock  ) );
331349				}
332350			}
333351			else  if  ( type  instanceof  ComponentType  compositeType  ) {
0 commit comments