15
15
import org .hibernate .cache .spi .access .SoftLock ;
16
16
import org .hibernate .engine .internal .Cascade ;
17
17
import org .hibernate .engine .internal .CascadePoint ;
18
+ import org .hibernate .engine .spi .ActionQueue ;
18
19
import org .hibernate .engine .spi .CascadingActions ;
19
20
import org .hibernate .engine .spi .EntityEntry ;
20
21
import org .hibernate .engine .spi .PersistenceContext ;
@@ -62,41 +63,7 @@ public void onRefresh(RefreshEvent event, RefreshContext refreshedAlready) {
62
63
final PersistenceContext persistenceContext = source .getPersistenceContextInternal ();
63
64
final Object object = event .getObject ();
64
65
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 );
100
67
}
101
68
else {
102
69
final Object entity = persistenceContext .unproxyAndReassociate ( object );
@@ -109,9 +76,58 @@ else if ( !isTransient ) {
109
76
}
110
77
}
111
78
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
+
112
128
private static boolean isTransient (RefreshEvent event , EventSource source , Object object ) {
113
129
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 );
115
131
}
116
132
117
133
private static void refresh (RefreshEvent event , RefreshContext refreshedAlready , Object object ) {
@@ -179,25 +195,26 @@ private static void refresh(
179
195
Object object ,
180
196
EventSource source ,
181
197
EntityPersister persister ,
182
- LazyInitializer lazyInitializer ,
198
+ LazyInitializer initializer ,
183
199
EntityEntry entry ,
184
200
Object id ,
185
- PersistenceContext persistenceContext ) {
201
+ PersistenceContext context ) {
186
202
if ( object != null ) {
187
203
final var instrumentationMetadata = persister .getBytecodeEnhancementMetadata ();
188
204
if ( instrumentationMetadata .isEnhancedForLazyLoading () ) {
189
205
final var interceptor = instrumentationMetadata .extractInterceptor ( object );
190
206
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.
192
209
interceptor .clearInitializedLazyFields ();
193
210
}
194
211
}
195
212
}
196
213
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 ) );
201
218
UnresolvableObjectException .throwIfNull ( result , id , persister .getEntityName () );
202
219
}
203
220
@@ -241,7 +258,7 @@ private static Object doRefresh(
241
258
if ( currentLockMode .greaterThan ( requestedLockMode ) ) {
242
259
// the requested lock-mode is less restrictive than the current one
243
260
// - pass along the current lock-mode (after accounting for WRITE)
244
- lockOptionsToUse = event . getLockOptions () .makeCopy ();
261
+ lockOptionsToUse = lockOptionsToUse .makeCopy ();
245
262
if ( currentLockMode == LockMode .WRITE
246
263
|| currentLockMode == LockMode .PESSIMISTIC_WRITE
247
264
|| currentLockMode == LockMode .PESSIMISTIC_READ ) {
@@ -272,7 +289,7 @@ private static Object doRefresh(
272
289
273
290
final Object result = persister .load ( id , object , lockOptionsToUse , source );
274
291
if ( result != null ) {
275
- // apply ` postRefreshLockMode` , if needed
292
+ // apply postRefreshLockMode, if needed
276
293
if ( postRefreshLockMode != null ) {
277
294
// if we get here, there was a previous entry, and we need to reset its lock mode
278
295
// - however, the refresh operation actually creates a new entry, so get it
@@ -312,6 +329,7 @@ private static void evictCachedCollections(EntityPersister persister, Object id,
312
329
private static void evictCachedCollections (Type [] types , Object id , EventSource source )
313
330
throws HibernateException {
314
331
final SessionFactoryImplementor factory = source .getFactory ();
332
+ final ActionQueue actionQueue = source .getActionQueue ();
315
333
final MappingMetamodelImplementor metamodel = factory .getMappingMetamodel ();
316
334
for ( Type type : types ) {
317
335
if ( type instanceof CollectionType collectionType ) {
@@ -327,7 +345,7 @@ private static void evictCachedCollections(Type[] types, Object id, EventSource
327
345
);
328
346
final SoftLock lock = cache .lockItem ( source , ck , null );
329
347
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 ) );
331
349
}
332
350
}
333
351
else if ( type instanceof ComponentType compositeType ) {
0 commit comments