⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.java

📁 hibernate-3.1.3-all-src.zip 面向对象的访问数据库工具
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
					//for sets, we should end the collection load after resolving
					//the entities, since we might call hashCode() on the elements
					//TODO: or we could do this polymorphically, and have two
					//      different operations implemented differently for arrays
					endCollectionLoad( resultSetId, session, collectionPersisters[i] );
				}
			}
		}
		
	}

	private void endCollectionLoad(
			final Object resultSetId, 
			final SessionImplementor session, 
			final CollectionPersister collectionPersister
	) {
		//this is a query and we are loading multiple instances of the same collection role
		session.getPersistenceContext().getCollectionLoadContext()
				.endLoadingCollections( collectionPersister, resultSetId, session );
	}

	protected List getResultList(List results) throws QueryException {
		return results;
	}

	/**
	 * Get the actual object that is returned in the user-visible result list.
	 * This empty implementation merely returns its first argument. This is
	 * overridden by some subclasses.
	 */
	protected Object getResultColumnOrRow(Object[] row, ResultSet rs, SessionImplementor session)
			throws SQLException, HibernateException {
		return row;
	}

	/**
	 * For missing objects associated by one-to-one with another object in the
	 * result set, register the fact that the the object is missing with the
	 * session.
	 */
	private void registerNonExists(
	        final EntityKey[] keys,
	        final Loadable[] persisters,
	        final SessionImplementor session) {
		
		final int[] owners = getOwners();
		if ( owners != null ) {
			
			EntityType[] ownerAssociationTypes = getOwnerAssociationTypes();
			for ( int i = 0; i < keys.length; i++ ) {
				
				int owner = owners[i];
				if ( owner > -1 ) {
					EntityKey ownerKey = keys[owner];
					if ( keys[i] == null && ownerKey != null ) {
						
						final PersistenceContext persistenceContext = session.getPersistenceContext();
						
						/*final boolean isPrimaryKey;
						final boolean isSpecialOneToOne;
						if ( ownerAssociationTypes == null || ownerAssociationTypes[i] == null ) {
							isPrimaryKey = true;
							isSpecialOneToOne = false;
						}
						else {
							isPrimaryKey = ownerAssociationTypes[i].getRHSUniqueKeyPropertyName()==null;
							isSpecialOneToOne = ownerAssociationTypes[i].getLHSPropertyName()!=null;
						}*/
						
						//TODO: can we *always* use the "null property" approach for everything?
						/*if ( isPrimaryKey && !isSpecialOneToOne ) {
							persistenceContext.addNonExistantEntityKey( 
									new EntityKey( ownerKey.getIdentifier(), persisters[i], session.getEntityMode() ) 
							);
						}
						else if ( isSpecialOneToOne ) {*/
						boolean isOneToOneAssociation = ownerAssociationTypes!=null && 
								ownerAssociationTypes[i]!=null && 
								ownerAssociationTypes[i].isOneToOne();
						if ( isOneToOneAssociation ) {
							persistenceContext.addNullProperty( ownerKey, 
									ownerAssociationTypes[i].getPropertyName() );
						}
						/*}
						else {
							persistenceContext.addNonExistantEntityUniqueKey( new EntityUniqueKey( 
									persisters[i].getEntityName(),
									ownerAssociationTypes[i].getRHSUniqueKeyPropertyName(),
									ownerKey.getIdentifier(),
									persisters[owner].getIdentifierType(),
									session.getEntityMode()
							) );
						}*/
					}
				}
			}
		}
	}

	/**
	 * Read one collection element from the current row of the JDBC result set
	 */
	private void readCollectionElement(
	        final Object optionalOwner,
	        final Serializable optionalKey,
	        final CollectionPersister persister,
	        final CollectionAliases descriptor,
	        final ResultSet rs,
	        final SessionImplementor session) 
	throws HibernateException, SQLException {

		final PersistenceContext persistenceContext = session.getPersistenceContext();

		final Serializable collectionRowKey = (Serializable) persister.readKey( 
				rs, 
				descriptor.getSuffixedKeyAliases(), 
				session 
			);
		
		if ( collectionRowKey != null ) {
			// we found a collection element in the result set

			if ( log.isDebugEnabled() ) {
				log.debug( 
						"found row of collection: " +
						MessageHelper.collectionInfoString( persister, collectionRowKey, getFactory() ) 
					);
			}

			Object owner = optionalOwner;
			if ( owner == null ) {
				owner = persistenceContext.getCollectionOwner( collectionRowKey, persister );
				if ( owner == null ) {
					//TODO: This is assertion is disabled because there is a bug that means the
					//	  original owner of a transient, uninitialized collection is not known
					//	  if the collection is re-referenced by a different object associated
					//	  with the current Session
					//throw new AssertionFailure("bug loading unowned collection");
				}
			}

			PersistentCollection rowCollection = persistenceContext.getCollectionLoadContext()
			        .getLoadingCollection( persister, collectionRowKey, rs, session.getEntityMode() );

			if ( rowCollection != null ) {
				rowCollection.readFrom( rs, persister, descriptor, owner );
			}

		}
		else if ( optionalKey != null ) {
			// we did not find a collection element in the result set, so we
			// ensure that a collection is created with the owner's identifier,
			// since what we have is an empty collection

			if ( log.isDebugEnabled() ) {
				log.debug( 
						"result set contains (possibly empty) collection: " +
						MessageHelper.collectionInfoString( persister, optionalKey, getFactory() ) 
					);
			}

			persistenceContext.getCollectionLoadContext()
					.getLoadingCollection( persister, optionalKey, rs, session.getEntityMode() ); //handle empty collection

		}

		// else no collection element, but also no owner

	}

	/**
	 * If this is a collection initializer, we need to tell the session that a collection
	 * is being initilized, to account for the possibility of the collection having
	 * no elements (hence no rows in the result set).
	 */
	private void handleEmptyCollections(
	        final Serializable[] keys,
	        final Object resultSetId,
	        final SessionImplementor session) throws HibernateException {

		if ( keys != null ) {
			// this is a collection initializer, so we must create a collection
			// for each of the passed-in keys, to account for the possibility
			// that the collection is empty and has no rows in the result set

			CollectionPersister[] collectionPersisters = getCollectionPersisters();
			for ( int j=0; j<collectionPersisters.length; j++ ) {
				for ( int i = 0; i < keys.length; i++ ) {
					//handle empty collections
	
					if ( log.isDebugEnabled() ) {
						log.debug( 
								"result set contains (possibly empty) collection: " +
								MessageHelper.collectionInfoString( collectionPersisters[j], keys[i], getFactory() ) 
							);
					}
	
					session.getPersistenceContext()
						.getCollectionLoadContext()
						.getLoadingCollection( 
								collectionPersisters[j], 
								keys[i], 
								resultSetId, 
								session.getEntityMode() 
							);
				}
			}

		}

		// else this is not a collection initializer (and empty collections will
		// be detected by looking for the owner's identifier in the result set)
	}

	/**
	 * Read a row of <tt>Key</tt>s from the <tt>ResultSet</tt> into the given array.
	 * Warning: this method is side-effecty.
	 * <p/>
	 * If an <tt>id</tt> is given, don't bother going to the <tt>ResultSet</tt>.
	 */
	private EntityKey getKeyFromResultSet(
	        final int i,
	        final Loadable persister,
	        final Serializable id,
	        final ResultSet rs,
	        final SessionImplementor session) throws HibernateException, SQLException {

		Serializable resultId;

		// if we know there is exactly 1 row, we can skip.
		// it would be great if we could _always_ skip this;
		// it is a problem for <key-many-to-one>

		if ( isSingleRowLoader() && id != null ) {
			resultId = id;
		}
		else {
			
			Type idType = persister.getIdentifierType();
			resultId = (Serializable) idType.nullSafeGet(
					rs,
					getEntityAliases()[i].getSuffixedKeyAliases(),
					session,
					null //problematic for <key-many-to-one>!
				);
			
			final boolean idIsResultId = id != null && 
					resultId != null && 
					idType.isEqual( id, resultId, session.getEntityMode(), factory );
			
			if ( idIsResultId ) resultId = id; //use the id passed in
		}

		return resultId == null ?
				null :
				new EntityKey( resultId, persister, session.getEntityMode() );
	}

	/**
	 * Check the version of the object in the <tt>ResultSet</tt> against
	 * the object version in the session cache, throwing an exception
	 * if the version numbers are different
	 */
	private void checkVersion(
	        final int i,
	        final Loadable persister,
	        final Serializable id,
	        final Object entity,
	        final ResultSet rs,
	        final SessionImplementor session) 
	throws HibernateException, SQLException {

		Object version = session.getPersistenceContext().getEntry( entity ).getVersion();

		if ( version != null ) { //null version means the object is in the process of being loaded somewhere else in the ResultSet
			VersionType versionType = persister.getVersionType();
			Object currentVersion = versionType.nullSafeGet(
					rs,
					getEntityAliases()[i].getSuffixedVersionAliases(),
					session,
					null
				);
			if ( !versionType.isEqual(version, currentVersion) ) {
				if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
					session.getFactory().getStatisticsImplementor()
							.optimisticFailure( persister.getEntityName() );
				}
				throw new StaleObjectStateException( persister.getEntityName(), id );
			}
		}

	}

	/**
	 * Resolve any ids for currently loaded objects, duplications within the
	 * <tt>ResultSet</tt>, etc. Instantiate empty objects to be initialized from the
	 * <tt>ResultSet</tt>. Return an array of objects (a row of results) and an
	 * array of booleans (by side-effect) that determine whether the corresponding
	 * object should be initialized.
	 */
	private Object[] getRow(
	        final ResultSet rs,
	        final Loadable[] persisters,
	        final EntityKey[] keys,
	        final Object optionalObject,
	        final EntityKey optionalObjectKey,
	        final LockMode[] lockModes,
	        final List hydratedObjects,
	        final SessionImplementor session) 
	throws HibernateException, SQLException {

		final int cols = persisters.length;
		final EntityAliases[] descriptors = getEntityAliases();

		if ( log.isDebugEnabled() ) {
			log.debug( 
					"result row: " + 
					StringHelper.toString( keys ) 
				);
		}

		final Object[] rowResults = new Object[cols];

		for ( int i = 0; i < cols; i++ ) {

			Object object = null;
			EntityKey key = keys[i];

			if ( keys[i] == null ) {
				//do nothing
			}
			else {

				//If the object is already loaded, return the loaded one
				object = session.getEntityUsingInterceptor( key );
				if ( object != null ) {
					//its already loaded so don't need to hydrate it
					instanceAlreadyLoaded( 
							rs,
							i,
							persisters[i],
							key,
							object,
							lockModes[i],
							session 
						);
				}
				else {
					object = instanceNotYetLoaded( 
							rs,
							i,
							persisters[i],
							descriptors[i].getRowIdAlias(),
							key,
							lockModes[i],
							optionalObjectKey,
							optionalObject,
							hydratedObjects,
							session 
						);
				}

			}

			rowResults[i] = object;

		}

		return rowResults;

	}

	/**
	 * The entity instance is already in the session cache
	 */
	private void instanceAlreadyLoaded(
	        final ResultSet rs,
	        final int i,
	        final Loadable persister,
	        final EntityKey key,
	        final Object object,
	        final LockMode lockMode,
	        final SessionImplementor session) 
	throws HibernateException, SQLException {

		if ( !persister.isInstance( object, session.getEntityMode() ) ) {
			throw new WrongClassException( 
					"loaded object was of wrong class", 
					key.getIdentifier(), 
					persister.getEntityName() 
				);
		}

		if ( LockMode.NONE != lockMode && upgradeLocks() ) { //no point doing this if NONE was requested

			final boolean isVersionCheckNeeded = persister.isVersioned() &&
					session.getPersistenceContext().getEntry(object)
							.getLockMode().lessThan( lockMode );
			// we don't need to worry about existing version being uninitialized
			// because this block isn't called by a re-entrant load (re-entrant
			// loads _always_ have lock mode NONE)
			if (isVersionCheckNeeded) {
				//we only check the version when _upgrading_ lock modes
				checkVersion( i, persister, key.getIdentifier(), object, rs, session );
				//we need to upgrade the lock mode to the mode requested
				session.getPersistenceContext().getEntry(object)
						.setLockMode(lockMode);
			}
		}
	}

	/**
	 * The entity instance is not in the session cache
	 */
	private Object instanceNotYetLoaded(
	        final ResultSet rs,
	        final int i,
	        final Loadable persister,
	        final String rowIdAlias,
	        final EntityKey key,
	        final LockMode lockMode,
	        final EntityKey optionalObjectKey,
	        final Object optionalObject,
	        final List hydratedObjects,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -