55
55
import org .hibernate .event .spi .PostLoadEventListener ;
56
56
import org .hibernate .internal .CoreMessageLogger ;
57
57
import org .hibernate .internal .util .collections .CollectionHelper ;
58
- import org .hibernate .internal .util .collections .IdentityMap ;
58
+ import org .hibernate .internal .util .collections .InstanceIdentityMap ;
59
59
import org .hibernate .metamodel .spi .MappingMetamodelImplementor ;
60
60
import org .hibernate .persister .collection .CollectionPersister ;
61
61
import org .hibernate .persister .entity .EntityPersister ;
@@ -131,7 +131,10 @@ the following fields are used in all circumstances, and are not worth (or not su
131
131
private IdentityHashMap <Object , PersistentCollection <?>> arrayHolders ;
132
132
133
133
// Identity map of CollectionEntry instances, by the collection wrapper
134
- private IdentityMap <PersistentCollection <?>, CollectionEntry > collectionEntries ;
134
+ private InstanceIdentityMap <PersistentCollection <?>, CollectionEntry > collectionEntries ;
135
+
136
+ // Current collection instance id
137
+ private transient int currentCollectionInstanceId ;
135
138
136
139
// Collection wrappers, by the CollectionKey
137
140
private HashMap <CollectionKey , PersistentCollection <?>> collectionsByKey ;
@@ -255,7 +258,7 @@ public void clear() {
255
258
256
259
final SharedSessionContractImplementor session = getSession ();
257
260
if ( collectionEntries != null ) {
258
- IdentityMap . onEachKey ( collectionEntries , k -> k .unsetSession ( session ) );
261
+ collectionEntries . forEach ( ( k , v ) -> k .unsetSession ( session ) );
259
262
}
260
263
261
264
arrayHolders = null ;
@@ -267,6 +270,7 @@ public void clear() {
267
270
collectionsByKey = null ;
268
271
nonlazyCollections = null ;
269
272
collectionEntries = null ;
273
+ currentCollectionInstanceId = 0 ;
270
274
unownedCollections = null ;
271
275
nullifiableEntityKeys = null ;
272
276
deletedUnloadedEntityKeys = null ;
@@ -614,7 +618,7 @@ public boolean isEntryFor(Object entity) {
614
618
615
619
@ Override
616
620
public CollectionEntry getCollectionEntry (PersistentCollection <?> coll ) {
617
- return collectionEntries == null ? null : collectionEntries .get ( coll );
621
+ return collectionEntries == null ? null : collectionEntries .get ( coll . $$_hibernate_getInstanceId (), coll );
618
622
}
619
623
620
624
@ Override
@@ -726,7 +730,7 @@ public EntityEntry addReferenceEntry(
726
730
727
731
@ Override
728
732
public boolean containsCollection (PersistentCollection <?> collection ) {
729
- return collectionEntries != null && collectionEntries .containsKey ( collection );
733
+ return collectionEntries != null && collectionEntries .containsKey ( collection . $$_hibernate_getInstanceId (), collection );
730
734
}
731
735
732
736
@ Override
@@ -1083,8 +1087,7 @@ public void replaceCollection(CollectionPersister persister, PersistentCollectio
1083
1087
"Replacement of not directly accessible collection found: " + oldCollection .getRole () );
1084
1088
}
1085
1089
assert !collection .isDirectlyAccessible ();
1086
- final IdentityMap <PersistentCollection <?>, CollectionEntry > collectionEntries = getOrInitializeCollectionEntries ();
1087
- final CollectionEntry oldEntry = collectionEntries .remove ( oldCollection );
1090
+ final CollectionEntry oldEntry = collectionEntries .remove ( oldCollection .$$_hibernate_getInstanceId (), oldCollection );
1088
1091
final CollectionEntry entry ;
1089
1092
if ( oldEntry .getLoadedPersister () != null ) {
1090
1093
// This is an already existing/loaded collection so ensure the loadedPersister is initialized
@@ -1094,7 +1097,7 @@ public void replaceCollection(CollectionPersister persister, PersistentCollectio
1094
1097
// A newly wrapped collection
1095
1098
entry = new CollectionEntry ( persister , collection );
1096
1099
}
1097
- collectionEntries . put ( collection , entry );
1100
+ putCollectionEntry ( collection , entry );
1098
1101
final Object key = collection .getKey ();
1099
1102
if ( key != null ) {
1100
1103
final CollectionKey collectionKey = new CollectionKey ( entry .getLoadedPersister (), key );
@@ -1113,7 +1116,7 @@ public void replaceCollection(CollectionPersister persister, PersistentCollectio
1113
1116
* @param key The key of the collection's entry.
1114
1117
*/
1115
1118
private void addCollection (PersistentCollection <?> coll , CollectionEntry entry , Object key ) {
1116
- getOrInitializeCollectionEntries (). put ( coll , entry );
1119
+ putCollectionEntry ( coll , entry );
1117
1120
final CollectionKey collectionKey = new CollectionKey ( entry .getLoadedPersister (), key );
1118
1121
final PersistentCollection <?> old = addCollectionByKey ( collectionKey , coll );
1119
1122
if ( old != null ) {
@@ -1126,11 +1129,12 @@ private void addCollection(PersistentCollection<?> coll, CollectionEntry entry,
1126
1129
}
1127
1130
}
1128
1131
1129
- private IdentityMap < PersistentCollection <?>, CollectionEntry > getOrInitializeCollectionEntries ( ) {
1132
+ private void putCollectionEntry ( PersistentCollection <?> collection , CollectionEntry entry ) {
1130
1133
if ( this .collectionEntries == null ) {
1131
- this .collectionEntries = IdentityMap . instantiateSequenced ( INIT_COLL_SIZE );
1134
+ this .collectionEntries = new InstanceIdentityMap <>( );
1132
1135
}
1133
- return this .collectionEntries ;
1136
+ collection .$$_hibernate_setInstanceId ( nextCollectionInstanceId () );
1137
+ this .collectionEntries .put ( collection , entry );
1134
1138
}
1135
1139
1136
1140
/**
@@ -1141,7 +1145,7 @@ private IdentityMap<PersistentCollection<?>, CollectionEntry> getOrInitializeCol
1141
1145
*/
1142
1146
private void addCollection (PersistentCollection <?> collection , CollectionPersister persister ) {
1143
1147
final CollectionEntry ce = new CollectionEntry ( persister , collection );
1144
- getOrInitializeCollectionEntries (). put ( collection , ce );
1148
+ putCollectionEntry ( collection , ce );
1145
1149
}
1146
1150
1147
1151
@ Override
@@ -1392,11 +1396,15 @@ public int getNumberOfManagedEntities() {
1392
1396
return collectionEntries ;
1393
1397
}
1394
1398
1399
+ private int nextCollectionInstanceId () {
1400
+ return currentCollectionInstanceId ++;
1401
+ }
1402
+
1395
1403
@ Override
1396
1404
public void forEachCollectionEntry (BiConsumer <PersistentCollection <?>, CollectionEntry > action , boolean concurrent ) {
1397
1405
if ( collectionEntries != null ) {
1398
1406
if ( concurrent ) {
1399
- for ( Entry <PersistentCollection <?>,CollectionEntry > entry : IdentityMap . concurrentEntries ( collectionEntries ) ) {
1407
+ for ( Entry <PersistentCollection <?>,CollectionEntry > entry : collectionEntries . toArray ( ) ) {
1400
1408
action .accept ( entry .getKey (), entry .getValue () );
1401
1409
}
1402
1410
}
@@ -2052,7 +2060,7 @@ public static StatefulPersistenceContext deserialize(
2052
2060
final PersistentCollection <?> pc = (PersistentCollection <?>) ois .readObject ();
2053
2061
final CollectionEntry ce = CollectionEntry .deserialize ( ois , session );
2054
2062
pc .setCurrentSession ( session );
2055
- rtn .getOrInitializeCollectionEntries (). put ( pc , ce );
2063
+ rtn .putCollectionEntry ( pc , ce );
2056
2064
}
2057
2065
2058
2066
count = ois .readInt ();
@@ -2194,7 +2202,12 @@ public int getCollectionEntriesSize() {
2194
2202
2195
2203
@ Override
2196
2204
public CollectionEntry removeCollectionEntry (PersistentCollection <?> collection ) {
2197
- return collectionEntries == null ? null : collectionEntries .remove (collection );
2205
+ if ( collectionEntries != null ) {
2206
+ return collectionEntries .remove ( collection .$$_hibernate_getInstanceId (), collection );
2207
+ }
2208
+ else {
2209
+ return null ;
2210
+ }
2198
2211
}
2199
2212
2200
2213
@ Override
0 commit comments