99import org .hibernate .action .internal .DelayedPostInsertIdentifier ;
1010import org .hibernate .collection .spi .PersistentCollection ;
1111import org .hibernate .engine .spi .CollectionEntry ;
12- import org .hibernate .engine .spi .EntityEntry ;
1312import org .hibernate .engine .spi .SessionFactoryImplementor ;
1413import org .hibernate .engine .spi .SessionImplementor ;
1514import org .hibernate .event .spi .EventSource ;
@@ -32,40 +31,39 @@ public final class Collections {
3231 /**
3332 * record the fact that this collection was dereferenced
3433 *
35- * @param coll The collection to be updated by un-reachability .
34+ * @param collection The collection to be updated by unreachability .
3635 * @param session The session
3736 */
38- public static void processUnreachableCollection (PersistentCollection <?> coll , SessionImplementor session ) {
39- if ( coll .getOwner () == null ) {
40- processNeverReferencedCollection ( coll , session );
37+ public static void processUnreachableCollection (PersistentCollection <?> collection , SessionImplementor session ) {
38+ if ( collection .getOwner () == null ) {
39+ processNeverReferencedCollection ( collection , session );
4140 }
4241 else {
43- processDereferencedCollection ( coll , session );
42+ processDereferencedCollection ( collection , session );
4443 }
4544 }
4645
47- private static void processDereferencedCollection (PersistentCollection <?> coll , SessionImplementor session ) {
46+ private static void processDereferencedCollection (PersistentCollection <?> collection , SessionImplementor session ) {
4847 final var persistenceContext = session .getPersistenceContextInternal ();
49- final var entry = persistenceContext .getCollectionEntry ( coll );
48+ final var entry = persistenceContext .getCollectionEntry ( collection );
5049 final var loadedPersister = entry .getLoadedPersister ();
5150
5251 if ( loadedPersister != null && log .isTraceEnabled () ) {
5352 log .trace ( "Collection dereferenced: "
54- + collectionInfoString ( loadedPersister , coll , entry .getLoadedKey (), session ) );
53+ + collectionInfoString ( loadedPersister , collection , entry .getLoadedKey (), session ) );
5554 }
5655
5756 // do a check
58- final boolean hasOrphanDelete = loadedPersister != null && loadedPersister .hasOrphanDelete ();
59- if ( hasOrphanDelete ) {
60- final Object ownerId = getOwnerId ( coll , session , loadedPersister );
57+ if ( loadedPersister != null && loadedPersister .hasOrphanDelete () ) {
58+ final Object ownerId = getOwnerId ( collection , session , loadedPersister );
6159 final var key = session .generateEntityKey ( ownerId , loadedPersister .getOwnerEntityPersister () );
6260 final Object owner = persistenceContext .getEntity ( key );
6361 if ( owner == null ) {
6462 throw new AssertionFailure ( "collection owner not associated with session: " + loadedPersister .getRole () );
6563 }
66- final EntityEntry e = persistenceContext .getEntry ( owner );
64+ final var entityEntry = persistenceContext .getEntry ( owner );
6765 //only collections belonging to deleted entities are allowed to be dereferenced in the case of orphan delete
68- if ( e != null && !e .getStatus ().isDeletedOrGone () ) {
66+ if ( entityEntry != null && !entityEntry .getStatus ().isDeletedOrGone () ) {
6967 throw new HibernateException (
7068 "A collection with orphan deletion was no longer referenced by the owning entity instance: "
7169 + loadedPersister .getRole ()
@@ -76,27 +74,27 @@ private static void processDereferencedCollection(PersistentCollection<?> coll,
7674 // do the work
7775 entry .setCurrentPersister ( null );
7876 entry .setCurrentKey ( null );
79- prepareCollectionForUpdate ( coll , entry , session .getFactory () );
77+ prepareCollectionForUpdate ( collection , entry , session .getFactory () );
8078
8179 }
8280
8381 private static Object getOwnerId (
84- PersistentCollection <?> coll ,
82+ PersistentCollection <?> collection ,
8583 SessionImplementor session ,
8684 CollectionPersister loadedPersister ) {
87-
85+ final Object owner = collection . getOwner ();
8886 Object ownerId =
8987 loadedPersister .getOwnerEntityPersister ()
90- .getIdentifier ( coll . getOwner () , session );
88+ .getIdentifier ( owner , session );
9189 if ( ownerId == null ) {
9290 // the owning entity may have been deleted and its identifier unset due to
93- // identifier- rollback; in which case, try to look up its identifier from
91+ // identifier rollback; in which case, try to look up its identifier from
9492 // the persistence context
9593 if ( session .getFactory ().getSessionFactoryOptions ()
9694 .isIdentifierRollbackEnabled () ) {
9795 final var ownerEntry =
9896 session .getPersistenceContextInternal ()
99- .getEntry ( coll . getOwner () );
97+ .getEntry ( owner );
10098 if ( ownerEntry != null ) {
10199 ownerId = ownerEntry .getId ();
102100 }
@@ -108,22 +106,22 @@ private static Object getOwnerId(
108106 return ownerId ;
109107 }
110108
111- private static void processNeverReferencedCollection (PersistentCollection <?> coll , SessionImplementor session )
109+ private static void processNeverReferencedCollection (PersistentCollection <?> collection , SessionImplementor session )
112110 throws HibernateException {
113111 final var entry =
114112 session .getPersistenceContextInternal ()
115- .getCollectionEntry ( coll );
113+ .getCollectionEntry ( collection );
114+ final var loadedPersister = entry .getLoadedPersister ();
115+ final Object loadedKey = entry .getLoadedKey ();
116116
117117 if ( log .isTraceEnabled () ) {
118- log .trace ( "Found collection with unloaded owner: " +
119- collectionInfoString ( entry . getLoadedPersister (), coll , entry . getLoadedKey () , session ) );
118+ log .trace ( "Found collection with unloaded owner: "
119+ + collectionInfoString ( loadedPersister , collection , loadedKey , session ) );
120120 }
121121
122- entry .setCurrentPersister ( entry .getLoadedPersister () );
123- entry .setCurrentKey ( entry .getLoadedKey () );
124-
125- prepareCollectionForUpdate ( coll , entry , session .getFactory () );
126-
122+ entry .setCurrentPersister ( loadedPersister );
123+ entry .setCurrentKey ( loadedKey );
124+ prepareCollectionForUpdate ( collection , entry , session .getFactory () );
127125 }
128126
129127 /**
@@ -140,11 +138,11 @@ public static void processReachableCollection(
140138 Object entity ,
141139 SessionImplementor session ) {
142140 collection .setOwner ( entity );
143- final var entry =
141+ final var collectionEntry =
144142 session .getPersistenceContextInternal ()
145143 .getCollectionEntry ( collection );
146144
147- if ( entry == null ) {
145+ if ( collectionEntry == null ) {
148146 // refer to comment in StatefulPersistenceContext.addCollection()
149147 throw new HibernateException ( "Found two representations of same collection: " + type .getRole () );
150148 }
@@ -154,49 +152,56 @@ public static void processReachableCollection(
154152 factory .getMappingMetamodel ()
155153 .getCollectionDescriptor ( type .getRole () );
156154
157- entry .setCurrentPersister ( persister );
155+ collectionEntry .setCurrentPersister ( persister );
158156 //TODO: better to pass the id in as an argument?
159- entry .setCurrentKey ( type .getKeyOfOwner ( entity , session ) );
157+ collectionEntry .setCurrentKey ( type .getKeyOfOwner ( entity , session ) );
160158
161159 final boolean isBytecodeEnhanced =
162160 persister .getOwnerEntityPersister ()
163161 .getBytecodeEnhancementMetadata ()
164162 .isEnhancedForLazyLoading ();
165163 if ( isBytecodeEnhanced && !collection .wasInitialized () ) {
166- // the class of the collection owner is enhanced for lazy loading and we found an un-initialized PersistentCollection
167- // - skip it
164+ // the class of the collection owner is enhanced for lazy loading,
165+ // and we found an un-initialized PersistentCollection, so skip it
168166 if ( log .isTraceEnabled () ) {
169167 log .trace ( "Skipping uninitialized bytecode-lazy collection: "
170- + collectionInfoString ( persister , collection , entry .getCurrentKey (), session ) );
168+ + collectionInfoString ( persister , collection , collectionEntry .getCurrentKey (), session ) );
171169 }
172- entry .setReached ( true );
173- entry .setProcessed ( true );
174- return ;
170+ collectionEntry .setReached ( true );
171+ collectionEntry .setProcessed ( true );
175172 }
176-
177173 // The CollectionEntry.isReached() stuff is just to detect any silly users
178174 // who set up circular or shared references between/to collections.
179- if ( entry .isReached () ) {
175+ else if ( collectionEntry .isReached () ) {
180176 // We've been here before
181177 throw new HibernateException ( "Found shared references to a collection: " + type .getRole () );
182178 }
179+ else {
180+ collectionEntry .setReached ( true );
181+ logReachedCollection ( collection , session , persister , collectionEntry );
182+ prepareCollectionForUpdate ( collection , collectionEntry , factory );
183+ }
184+ }
183185
184- entry .setReached ( true );
185-
186+ private static void logReachedCollection (
187+ PersistentCollection <?> collection ,
188+ SessionImplementor session ,
189+ CollectionPersister persister ,
190+ CollectionEntry collectionEntry ) {
186191 if ( log .isTraceEnabled () ) {
187192 if ( collection .wasInitialized () ) {
188193 log .tracef (
189194 "Collection found: %s, was: %s (initialized)" ,
190195 collectionInfoString (
191196 persister ,
192197 collection ,
193- entry .getCurrentKey (),
198+ collectionEntry .getCurrentKey (),
194199 session
195200 ),
196201 collectionInfoString (
197- entry .getLoadedPersister (),
202+ collectionEntry .getLoadedPersister (),
198203 collection ,
199- entry .getLoadedKey (),
204+ collectionEntry .getLoadedKey (),
200205 session
201206 )
202207 );
@@ -207,20 +212,18 @@ public static void processReachableCollection(
207212 collectionInfoString (
208213 persister ,
209214 collection ,
210- entry .getCurrentKey (),
215+ collectionEntry .getCurrentKey (),
211216 session
212217 ),
213218 collectionInfoString (
214- entry .getLoadedPersister (),
219+ collectionEntry .getLoadedPersister (),
215220 collection ,
216- entry .getLoadedKey (),
221+ collectionEntry .getLoadedKey (),
217222 session
218223 )
219224 );
220225 }
221226 }
222-
223- prepareCollectionForUpdate ( collection , entry , factory );
224227 }
225228
226229 /**
@@ -230,23 +233,22 @@ public static void processReachableCollection(
230233 */
231234 private static void prepareCollectionForUpdate (
232235 PersistentCollection <?> collection ,
233- CollectionEntry entry ,
236+ CollectionEntry collectionEntry ,
234237 SessionFactoryImplementor factory ) {
235- if ( entry .isProcessed () ) {
238+ if ( collectionEntry .isProcessed () ) {
236239 throw new AssertionFailure ( "collection was processed twice by flush()" );
237240 }
238- entry .setProcessed ( true );
241+ collectionEntry .setProcessed ( true );
239242
240- final var loadedPersister = entry .getLoadedPersister ();
241- final var currentPersister = entry .getCurrentPersister ();
243+ final var loadedPersister = collectionEntry .getLoadedPersister ();
244+ final var currentPersister = collectionEntry .getCurrentPersister ();
242245 if ( loadedPersister != null || currentPersister != null ) {
243246 // it is or was referenced _somewhere_
244247
245-
246248 // if either its role changed, or its key changed
247249 final boolean ownerChanged =
248250 loadedPersister != currentPersister
249- || wasKeyChanged ( entry , factory , currentPersister );
251+ || wasKeyChanged ( collectionEntry , factory , currentPersister );
250252
251253 if ( ownerChanged ) {
252254 // do a check
@@ -262,21 +264,21 @@ private static void prepareCollectionForUpdate(
262264
263265 // do the work
264266 if ( currentPersister != null ) {
265- entry .setDorecreate ( true );
267+ collectionEntry .setDorecreate ( true );
266268 }
267269
268270 if ( loadedPersister != null ) {
269271 // we will need to remove the old entries
270- entry .setDoremove ( true );
271- if ( entry .isDorecreate () ) {
272+ collectionEntry .setDoremove ( true );
273+ if ( collectionEntry .isDorecreate () ) {
272274 log .trace ( "Forcing collection initialization" );
273275 collection .forceInitialization ();
274276 }
275277 }
276278 }
277279 else if ( collection .isDirty () ) {
278280 // the collection's elements have changed
279- entry .setDoupdate ( true );
281+ collectionEntry .setDoupdate ( true );
280282 }
281283 }
282284 }
@@ -289,7 +291,7 @@ private static boolean wasKeyChanged(
289291 CollectionEntry entry , SessionFactoryImplementor factory , CollectionPersister currentPersister ) {
290292 return currentPersister != null
291293 && !currentPersister .getKeyType ().isEqual ( entry .getLoadedKey (), entry .getCurrentKey (), factory )
292- && !(entry .getLoadedKey () instanceof DelayedPostInsertIdentifier );
294+ && !( entry .getLoadedKey () instanceof DelayedPostInsertIdentifier );
293295 }
294296
295297 /**
@@ -315,5 +317,4 @@ public static boolean skipRemoval(EventSource session, CollectionPersister persi
315317 */
316318 private Collections () {
317319 }
318-
319320}
0 commit comments