@@ -110,20 +110,18 @@ else if ( target instanceof Map<?, ?> map ) {
110
110
}
111
111
else {
112
112
final PersistenceContext persistenceContext = session .getPersistenceContext ();
113
- final PersistentCollection <?> collectionHolder = persistenceContext .getCollectionHolder ( target );
114
- if ( collectionHolder != null ) {
115
- if ( collectionHolder instanceof PersistentArrayHolder <?> arrayHolder ) {
116
- persistenceContext .removeCollectionHolder ( target );
117
- arrayHolder .beginRead ();
118
- final PluralAttributeMapping attributeMapping =
119
- persistenceContext .getCollectionEntry ( collectionHolder )
120
- .getLoadedPersister ().getAttributeMapping ();
121
- arrayHolder .injectLoadedState ( attributeMapping , null );
122
- arrayHolder .endRead ();
123
- arrayHolder .dirty ();
124
- persistenceContext .addCollectionHolder ( collectionHolder );
125
- return arrayHolder .getArray ();
126
- }
113
+ if ( persistenceContext .getCollectionHolder ( target )
114
+ instanceof PersistentArrayHolder <?> arrayHolder ) {
115
+ persistenceContext .removeCollectionHolder ( target );
116
+ arrayHolder .beginRead ();
117
+ final PluralAttributeMapping attributeMapping =
118
+ persistenceContext .getCollectionEntry ( arrayHolder )
119
+ .getLoadedPersister ().getAttributeMapping ();
120
+ arrayHolder .injectLoadedState ( attributeMapping , null );
121
+ arrayHolder .endRead ();
122
+ arrayHolder .dirty ();
123
+ persistenceContext .addCollectionHolder ( arrayHolder );
124
+ return arrayHolder .getArray ();
127
125
}
128
126
}
129
127
return null ;
@@ -142,8 +140,9 @@ private static Object replaceUninitializedOriginal(
142
140
// A managed entity with an uninitialized collection is being merged,
143
141
// We need to replace any detached entities in the queued operations
144
142
// with managed copies.
145
- final AbstractPersistentCollection <?> pc = (AbstractPersistentCollection <?>) original ;
146
- pc .replaceQueuedOperationValues (
143
+ final AbstractPersistentCollection <?> collection =
144
+ (AbstractPersistentCollection <?>) original ;
145
+ collection .replaceQueuedOperationValues (
147
146
session .getFactory ()
148
147
.getMappingMetamodel ()
149
148
.getCollectionDescriptor ( type .getRole () ), copyCache
@@ -182,18 +181,20 @@ private static CompletionStage<Object> replaceOriginal(
182
181
).thenCompose ( result -> {
183
182
if ( original == target ) {
184
183
// get the elements back into the target making sure to handle dirty flag
185
- final boolean wasClean =
186
- target instanceof PersistentCollection <?> collection
187
- && !collection .isDirty ();
188
184
//TODO: this is a little inefficient, don't need to do a whole
189
185
// deep replaceElements() call
190
- return replaceElements ( type , result , target , owner , copyCache , session )
191
- .thenApply ( unused -> {
192
- if ( wasClean ) {
193
- ( (PersistentCollection <?>) target ).clearDirty ();
194
- }
195
- return target ;
196
- } );
186
+ final CompletionStage <Object > replaced =
187
+ replaceElements ( type , result , target , owner , copyCache , session );
188
+ if ( target instanceof PersistentCollection <?> collection
189
+ && !collection .isDirty () ) {
190
+ return replaced .thenApply ( unused -> {
191
+ collection .clearDirty ();
192
+ return target ;
193
+ } );
194
+ }
195
+ else {
196
+ return replaced .thenApply ( unused -> target );
197
+ }
197
198
}
198
199
else {
199
200
return completedFuture ( result );
@@ -220,7 +221,7 @@ else if ( type instanceof CustomCollectionType ) {
220
221
else if ( type instanceof MapType ) {
221
222
return replaceMapTypeElements (
222
223
type ,
223
- (Map <Object , Object >) original ,
224
+ (Map <?, ? >) original ,
224
225
(Map <Object , Object >) target ,
225
226
owner ,
226
227
copyCache ,
@@ -247,64 +248,70 @@ private static CompletionStage<Object> replaceCollectionTypeElements(
247
248
Map <Object , Object > copyCache ,
248
249
SessionImplementor session ) {
249
250
result .clear ();
250
-
251
251
// copy elements into newly empty target collection
252
252
final Type elemType = type .getElementType ( session .getFactory () );
253
- return loop (
254
- (Collection <Object >) original , o -> getReplace ( elemType , o , owner , session , copyCache )
255
- .thenAccept ( result ::add )
256
- ).thenCompose ( unused -> {
257
- // if the original is a PersistentCollection, and that original
258
- // was not flagged as dirty, then reset the target's dirty flag
259
- // here after the copy operation.
260
- // </p>
261
- // One thing to be careful of here is a "bare" original collection
262
- // in which case we should never ever ever reset the dirty flag
263
- // on the target because we simply do not know...
264
- if ( original instanceof PersistentCollection <?> originalPersistentCollection
265
- && result instanceof PersistentCollection <?> resultPersistentCollection ) {
266
- return preserveSnapshot (
267
- originalPersistentCollection , resultPersistentCollection ,
268
- elemType , owner , copyCache , session
269
- ).thenApply ( v -> {
270
- if ( !originalPersistentCollection .isDirty () ) {
271
- resultPersistentCollection .clearDirty ();
272
- }
273
- return result ;
274
- } );
275
- }
276
- else {
277
- return completedFuture ( result );
278
- }
279
- } );
253
+ return loop ( (Collection <?>) original ,
254
+ o -> getReplace ( elemType , o , owner , session , copyCache )
255
+ .thenAccept ( result ::add ) )
256
+ .thenCompose ( v -> preserveSnapshotIfNecessary ( original , result , owner , copyCache , session , elemType ) );
257
+ }
258
+
259
+ private static CompletionStage <Object > preserveSnapshotIfNecessary (
260
+ Object original ,
261
+ Collection <Object > result ,
262
+ Object owner ,
263
+ Map <Object , Object > copyCache ,
264
+ SessionImplementor session ,
265
+ Type elemType ) {
266
+ // if the original is a PersistentCollection, and that original
267
+ // was not flagged as dirty, then reset the target's dirty flag
268
+ // here after the copy operation.
269
+ // </p>
270
+ // One thing to be careful of here is a "bare" original collection
271
+ // in which case we should never ever ever reset the dirty flag
272
+ // on the target because we simply do not know...
273
+ if ( original instanceof PersistentCollection <?> originalCollection
274
+ && result instanceof PersistentCollection <?> resultCollection ) {
275
+ return preserveSnapshot (
276
+ originalCollection , resultCollection ,
277
+ elemType , owner , copyCache , session
278
+ ).thenApply ( v -> {
279
+ if ( !originalCollection .isDirty () ) {
280
+ resultCollection .clearDirty ();
281
+ }
282
+ return result ;
283
+ } );
284
+ }
285
+ else {
286
+ return completedFuture ( result );
287
+ }
280
288
}
281
289
282
290
private static CompletionStage <Object > replaceMapTypeElements (
283
291
CollectionType type ,
284
- Map <Object , Object > original ,
292
+ Map <?, ? > original ,
285
293
Map <Object , Object > target ,
286
294
Object owner ,
287
295
Map <Object , Object > copyCache ,
288
296
SessionImplementor session ) {
289
- final CollectionPersister persister = session .getFactory ().getRuntimeMetamodels ()
290
- .getMappingMetamodel ().getCollectionDescriptor ( type .getRole () );
291
- final Map <Object , Object > result = target ;
292
- result .clear ();
293
-
297
+ final CollectionPersister persister =
298
+ session .getFactory ().getRuntimeMetamodels ().getMappingMetamodel ()
299
+ .getCollectionDescriptor ( type .getRole () );
300
+ target .clear ();
294
301
return loop (
295
302
original .entrySet (), entry -> {
296
- final Map .Entry <Object , Object > me = entry ;
303
+ final Map .Entry <?, ? > me = entry ;
297
304
return getReplace ( persister .getIndexType (), me .getKey (), owner , session , copyCache )
298
305
.thenCompose ( key -> getReplace (
299
306
persister .getElementType (),
300
307
me .getValue (),
301
308
owner ,
302
309
session ,
303
310
copyCache
304
- ).thenAccept ( value -> result .put ( key , value ) )
311
+ ).thenAccept ( value -> target .put ( key , value ) )
305
312
);
306
313
}
307
- ).thenApply ( unused -> result );
314
+ ).thenApply ( unused -> target );
308
315
}
309
316
310
317
private static CompletionStage <Object > replaceArrayTypeElements (
@@ -325,8 +332,8 @@ private static CompletionStage<Object> replaceArrayTypeElements(
325
332
}
326
333
327
334
final Type elemType = type .getElementType ( session .getFactory () );
328
- return loop (
329
- 0 , length , i -> getReplace ( elemType , Array .get ( original , i ), owner , session , copyCache )
335
+ return loop ( 0 , length ,
336
+ i -> getReplace ( elemType , Array .get ( original , i ), owner , session , copyCache )
330
337
.thenApply ( o -> {
331
338
Array .set ( result , i , o );
332
339
return result ;
@@ -345,18 +352,14 @@ private static CompletionStage<Object> getReplace(
345
352
346
353
private static CompletionStage <Object > getReplace (
347
354
Type elemType ,
348
- Object o ,
355
+ Object object ,
349
356
Object target ,
350
357
Object owner ,
351
358
SessionImplementor session ,
352
359
Map <Object , Object > copyCache ) {
353
- if ( elemType instanceof EntityType ) {
354
- return EntityTypes .replace ( (EntityType ) elemType , o , target , session , owner , copyCache );
355
- }
356
- else {
357
- final Object replace = elemType .replace ( o , target , session , owner , copyCache );
358
- return completedFuture ( replace );
359
- }
360
+ return elemType instanceof EntityType entityType
361
+ ? EntityTypes .replace ( entityType , object , target , session , owner , copyCache )
362
+ : completedFuture ( elemType .replace ( object , target , session , owner , copyCache ) );
360
363
}
361
364
362
365
/**
@@ -374,7 +377,9 @@ private static CompletionStage<Void> preserveSnapshot(
374
377
return createSnapshot ( original , result , elemType , owner , copyCache , session )
375
378
.thenAccept ( serializable -> ce .resetStoredSnapshot ( result , serializable ) );
376
379
}
377
- return voidFuture ();
380
+ else {
381
+ return voidFuture ();
382
+ }
378
383
}
379
384
380
385
/**
@@ -412,38 +417,35 @@ private static CompletionStage<Serializable> createArraySnapshot(
412
417
Object owner ,
413
418
Map <Object , Object > copyCache ,
414
419
SessionImplementor session ) {
415
- return loop (
416
- 0 , array . length , i -> getReplace ( elemType , array [i ], owner , session , copyCache )
420
+ return loop ( 0 , array . length ,
421
+ i -> getReplace ( elemType , array [i ], owner , session , copyCache )
417
422
.thenAccept ( o -> array [i ] = o )
418
423
).thenApply ( unused -> array );
419
424
}
420
425
421
426
/**
422
427
* @see CollectionType#createMapSnapshot(Map, PersistentCollection, Type, Object, Map, SharedSessionContractImplementor)
423
428
*/
424
- private static CompletionStage <Serializable > createMapSnapshot (
425
- Map <?, ? > map ,
429
+ private static < K , V > CompletionStage <Serializable > createMapSnapshot (
430
+ Map <K , V > map ,
426
431
PersistentCollection <?> result ,
427
432
Type elemType ,
428
433
Object owner ,
429
434
Map <Object , Object > copyCache ,
430
435
SessionImplementor session ) {
431
436
final Map <?, ?> resultSnapshot = (Map <?, ?>) result .getStoredSnapshot ();
432
- final Map <Object , Object > targetMap ;
433
- if ( map instanceof SortedMap <?, ?> sortedMap ) {
434
- //noinspection unchecked, rawtypes
435
- targetMap = new TreeMap ( sortedMap .comparator () );
436
- }
437
- else {
438
- targetMap = mapOfSize ( map .size () );
439
- }
440
- return loop (
441
- map .entrySet (), entry ->
442
- getReplace ( elemType , entry .getValue (), resultSnapshot , owner , session , copyCache )
443
- .thenAccept ( newValue -> {
444
- final Object key = entry .getKey ();
445
- targetMap .put ( key == entry .getValue () ? newValue : key , newValue );
446
- } )
437
+ final Map <K , V > targetMap =
438
+ map instanceof SortedMap <K , V > sortedMap
439
+ ? new TreeMap <>( sortedMap .comparator () )
440
+ : mapOfSize (map .size ());
441
+ return loop ( map .entrySet (),
442
+ entry -> getReplace ( elemType , entry .getValue (), resultSnapshot , owner , session , copyCache )
443
+ .thenAccept ( newValue -> {
444
+ final K key = entry .getKey ();
445
+ final V value = entry .getValue ();
446
+ //noinspection unchecked
447
+ targetMap .put ( key == value ? (K ) newValue : key , (V ) newValue );
448
+ } )
447
449
).thenApply ( v -> (Serializable ) targetMap );
448
450
}
449
451
@@ -457,8 +459,8 @@ private static CompletionStage<Serializable> createListSnapshot(
457
459
Map <Object , Object > copyCache ,
458
460
SessionImplementor session ) {
459
461
final ArrayList <Object > targetList = new ArrayList <>( list .size () );
460
- return loop (
461
- list , obj -> getReplace ( elemType , obj , owner , session , copyCache )
462
+ return loop ( list ,
463
+ obj -> getReplace ( elemType , obj , owner , session , copyCache )
462
464
.thenAccept ( targetList ::add )
463
465
).thenApply ( unused -> targetList );
464
466
}
@@ -472,9 +474,9 @@ private static Object instantiateResultIfNecessary(CollectionType type, Object o
472
474
// by default just use an unanticipated capacity since we don't
473
475
// know how to extract the capacity to use from original here...
474
476
return target == null
475
- || target == original
476
- || target == UNFETCHED_PROPERTY
477
- || target instanceof PersistentCollection <?> collection && collection .isWrapper ( original )
477
+ || target == original
478
+ || target == UNFETCHED_PROPERTY
479
+ || target instanceof PersistentCollection <?> collection && collection .isWrapper ( original )
478
480
? type .instantiate ( -1 )
479
481
: target ;
480
482
}
0 commit comments