Project

General

Profile

Revision 445d2b80

ID445d2b8017d4533b645c55435ba5869ce42c632a
Parent c44864dc
Child 78716654

Added by Andreas Müller 2 months ago

ref #9204 final changes to AbstractPersistentCollection (also seem to be not really critical)

View differences:

eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java
115 115
	private static final long serialVersionUID = 7094296207968006972L;
116 116

  
117 117
	private transient SessionImplementor session;
118
	private boolean isTempSession = false;
118 119
	private boolean initialized;
119 120
	private transient List<DelayedOperation> operationQueue;
120 121
	private transient boolean directlyAccessible;
......
130 131
	private Serializable storedSnapshot;
131 132

  
132 133
	private String sessionFactoryUuid;
133
	private boolean specjLazyLoad = false;
134
	private boolean allowLoadOutsideTransaction;
134 135

  
135 136
	/**
136 137
	 * Not called by Hibernate, but used by non-JDK serialization,
......
256 257
	}
257 258

  
258 259
	private <T> T withTemporarySessionIfNeeded(LazyInitializationWork<T> lazyInitializationWork) {
259
		SessionImplementor originalSession = null;
260
		boolean isTempSession = false;
261
		boolean isJTA = false;
260
		SessionImplementor tempSession = null;
262 261

  
263 262
		if ( session == null ) {
264
			if ( specjLazyLoad ) {
265
				session = openTemporarySessionForLoading();
266
				isTempSession = true;
263
			if ( allowLoadOutsideTransaction ) {
264
				tempSession = openTemporarySessionForLoading();
267 265
			}
268 266
			else {
269 267
				throwLazyInitializationException( "could not initialize proxy - no Session" );
270 268
			}
271 269
		}
272 270
		else if ( !session.isOpen() ) {
273
			if ( specjLazyLoad ) {
274
				originalSession = session;
275
				session = openTemporarySessionForLoading();
276
				isTempSession = true;
271
			if ( allowLoadOutsideTransaction ) {
272
				tempSession = openTemporarySessionForLoading();
277 273
			}
278 274
			else {
279 275
				throwLazyInitializationException( "could not initialize proxy - the owning Session was closed" );
280 276
			}
281 277
		}
282 278
		else if ( !session.isConnected() ) {
283
			if ( specjLazyLoad ) {
284
				originalSession = session;
285
				session = openTemporarySessionForLoading();
286
				isTempSession = true;
279
			if ( allowLoadOutsideTransaction ) {
280
				tempSession = openTemporarySessionForLoading();
287 281
			}
288 282
			else {
289 283
				throwLazyInitializationException( "could not initialize proxy - the owning Session is disconnected" );
290 284
			}
291 285
		}
292 286

  
293
		if ( isTempSession ) {
294
			// TODO: On the next major release, add an
295
			// 'isJTA' or 'getTransactionFactory' method to Session.
296
			/*isJTA = session.getTransactionCoordinator()
297
					.getTransactionContext().getTransactionEnvironment()
298
					.getTransactionFactory()
299
					.compatibleWithJtaSynchronization();*/
287

  
288
		SessionImplementor originalSession = null;
289
		boolean isJTA = false;
290

  
291
		if ( tempSession != null ) {
292
			isTempSession = true;
293
			originalSession = session;
294
			session = tempSession;
295

  
296

  
300 297
			isJTA = session.getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta();
301 298
			
302 299
			if ( !isJTA ) {
......
318 315
			return lazyInitializationWork.doWork();
319 316
		}
320 317
		finally {
321
			if ( isTempSession ) {
318
			if ( tempSession != null ) {
322 319
				// make sure the just opened temp session gets closed!
320
				isTempSession = false;
321
				session = originalSession;
322

  
323 323
				try {
324 324
					if ( !isJTA ) {
325
						( ( Session) session ).getTransaction().commit();
325
						( (Session) tempSession ).getTransaction().commit();
326 326
					}
327
					( (Session) session ).close();
327
					( (Session) tempSession ).close();
328 328
				}
329 329
				catch (Exception e) {
330 330
					LOG.warn( "Unable to close temporary session used to load lazy collection associated to no session" );
331 331
				}
332
				session = originalSession;
333 332
			}
334 333
		}
335 334
	}
......
698 697
	public final boolean unsetSession(SessionImplementor currentSession) {
699 698
		prepareForPossibleLoadingOutsideTransaction();
700 699
		if ( currentSession == this.session ) {
701
			this.session = null;
700
			if ( !isTempSession ) {
701
				this.session = null;
702
			}
702 703
			return true;
703 704
		}
704 705
		else {
706
			if ( this.session != null ) {
707
				LOG.logCannotUnsetUnexpectedSessionInCollection( generateUnexpectedSessionStateMessage( currentSession ) );
708
			}
705 709
			return false;
706 710
		}
707 711
	}
708 712

  
709 713
	protected void prepareForPossibleLoadingOutsideTransaction() {
710 714
		if ( session != null ) {
711
			specjLazyLoad = session.getFactory().getSettings().isInitializeLazyStateOutsideTransactionsEnabled();
715
			allowLoadOutsideTransaction = session.getFactory().getSessionFactoryOptions().isInitializeLazyStateOutsideTransactionsEnabled();
712 716

  
713
			if ( specjLazyLoad && sessionFactoryUuid == null ) {
714
				try {
715
					sessionFactoryUuid = (String) session.getFactory().getReference().get( "uuid" ).getContent();
716
				}
717
				catch (NamingException e) {
718
					//not much we can do if this fails...
719
				}
717
			if ( allowLoadOutsideTransaction && sessionFactoryUuid == null ) {
718
				sessionFactoryUuid = session.getFactory().getUuid();
720 719
			}
721 720
		}
722 721
	}
......
727 726
			return false;
728 727
		}
729 728
		else {
730
			if ( isConnectedToSession() ) {
731
				CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
732
				if ( ce == null ) {
729
			if ( this.session != null ) {
730
				final String msg = generateUnexpectedSessionStateMessage( session );
731
				if ( isConnectedToSession() ) {
733 732
					throw new HibernateException(
734
							"Illegal attempt to associate a collection with two open sessions"
733
							"Illegal attempt to associate a collection with two open sessions. " + msg
735 734
					);
736 735
				}
737 736
				else {
738
					throw new HibernateException(
739
							"Illegal attempt to associate a collection with two open sessions: " +
740
									MessageHelper.collectionInfoString(
741
											ce.getLoadedPersister(), this,
742
											ce.getLoadedKey(), session
743
									)
744
					);
737
					LOG.logUnexpectedSessionInCollectionNotConnected( msg );
738
					this.session = session;
739
					return true;
745 740
				}
746 741
			}
747 742
			else {
......
751 746
		}
752 747
	}
753 748

  
754
	/**
755
	 * Do we need to completely recreate this collection when it changes?
756
	 */
749
	private String generateUnexpectedSessionStateMessage(SessionImplementor session) {
750
		// NOTE: If this.session != null, this.session may be operating on this collection
751
		// (e.g., by changing this.role, this.key, or even this.session) in a different thread.
752

  
753
		// Grab the current role and key (it can still get changed by this.session...)
754
		// If this collection is connected to this.session, then this.role and this.key should
755
		// be consistent with the CollectionEntry in this.session (as long as this.session doesn't
756
		// change it). Don't access the CollectionEntry in this.session because that could result
757
		// in multi-threaded access to this.session.
758
		final String roleCurrent = role;
759
		final Serializable keyCurrent = key;
760

  
761
		final StringBuilder sb = new StringBuilder( "Collection : " );
762
		if ( roleCurrent != null ) {
763
			sb.append( MessageHelper.collectionInfoString( roleCurrent, keyCurrent ) );
764
		}
765
		else {
766
			final CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
767
			if ( ce != null ) {
768
				sb.append(
769
						MessageHelper.collectionInfoString(
770
								ce.getLoadedPersister(),
771
								this,
772
								ce.getLoadedKey(),
773
								session
774
						)
775
				);
776
			}
777
			else {
778
				sb.append( "<unknown>" );
779
			}
780
		}
781
		// only include the collection contents if debug logging
782
		if ( LOG.isDebugEnabled() ) {
783
			final String collectionContents = wasInitialized() ? toString() : "<uninitialized>";
784
			sb.append( "\nCollection contents: [" ).append( collectionContents ).append( "]" );
785
		}
786
		return sb.toString();
787
	}
788

  
757 789
	@Override
758 790
	public boolean needsRecreate(CollectionPersister persister) {
759 791
		// Workaround for situations like HHH-7072.  If the collection element is a component that consists entirely
......
787 819
			if ( initializing ) {
788 820
				throw new AssertionFailure( "force initialize loading collection" );
789 821
			}
790
			if ( session == null ) {
791
				throw new HibernateException( "collection is not associated with any session" );
792
			}
793
			if ( !session.isConnected() ) {
794
				throw new HibernateException( "disconnected session" );
795
			}
796
			session.initializeCollection( this, false );
822
			initialize( false );
797 823
		}
798 824
	}
799 825

  

Also available in: Unified diff

Add picture from clipboard (Maximum size: 40 MB)