FileDocCategorySizeDatePackage
BasicCollectionJoinWalker.javaAPI DocHibernate 3.2.54936Thu May 04 11:23:44 BST 2006org.hibernate.loader.collection

BasicCollectionJoinWalker

public class BasicCollectionJoinWalker extends CollectionJoinWalker
Walker for collections of values and many-to-many associations
see
BasicCollectionLoader
author
Gavin King

Fields Summary
private final org.hibernate.persister.collection.QueryableCollection
collectionPersister
Constructors Summary
public BasicCollectionJoinWalker(org.hibernate.persister.collection.QueryableCollection collectionPersister, int batchSize, String subquery, org.hibernate.engine.SessionFactoryImplementor factory, Map enabledFilters)


		super(factory, enabledFilters);

		this.collectionPersister = collectionPersister;

		String alias = generateRootAlias( collectionPersister.getRole() );

		walkCollectionTree(collectionPersister, alias);

		List allAssociations = new ArrayList();
		allAssociations.addAll(associations);
		allAssociations.add( new OuterJoinableAssociation( 
				collectionPersister.getCollectionType(),
				null, 
				null, 
				alias, 
				JoinFragment.LEFT_OUTER_JOIN, 
				getFactory(), 
				CollectionHelper.EMPTY_MAP 
			) );

		initPersisters(allAssociations, LockMode.NONE);
		initStatementString(alias, batchSize, subquery);

	
Methods Summary
protected intgetJoinType(org.hibernate.type.AssociationType type, org.hibernate.FetchMode config, java.lang.String path, java.util.Set visitedAssociations, java.lang.String lhsTable, java.lang.String[] lhsColumns, boolean nullable, int currentDepth)
We can use an inner join for first many-to-many association


		int joinType = super.getJoinType(
				type, 
				config, 
				path, 
				lhsTable, 
				lhsColumns, 
				nullable, 
				currentDepth,
				null
			);
		//we can use an inner join for the many-to-many
		if ( joinType==JoinFragment.LEFT_OUTER_JOIN && "".equals(path) ) {
			joinType=JoinFragment.INNER_JOIN;
		}
		return joinType;
	
private voidinitStatementString(java.lang.String alias, int batchSize, java.lang.String subquery)


		final int joins = countEntityPersisters( associations );
		final int collectionJoins = countCollectionPersisters( associations ) + 1;

		suffixes = BasicLoader.generateSuffixes( joins );
		collectionSuffixes = BasicLoader.generateSuffixes( joins, collectionJoins );

		StringBuffer whereString = whereString(
				alias, 
				collectionPersister.getKeyColumnNames(), 
				subquery,
				batchSize
			);

		String manyToManyOrderBy = "";
		String filter = collectionPersister.filterFragment( alias, getEnabledFilters() );
		if ( collectionPersister.isManyToMany() ) {
			// from the collection of associations, locate OJA for the
			// ManyToOne corresponding to this persister to fully
			// define the many-to-many; we need that OJA so that we can
			// use its alias here
			// TODO : is there a better way here?
			Iterator itr = associations.iterator();
			AssociationType associationType = ( AssociationType ) collectionPersister.getElementType();
			while ( itr.hasNext() ) {
				OuterJoinableAssociation oja = ( OuterJoinableAssociation ) itr.next();
				if ( oja.getJoinableType() == associationType ) {
					// we found it
					filter += collectionPersister.getManyToManyFilterFragment( 
							oja.getRHSAlias(), 
							getEnabledFilters() 
						);
						manyToManyOrderBy += collectionPersister.getManyToManyOrderByString( oja.getRHSAlias() );
				}
			}
		}
		whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) );

		JoinFragment ojf = mergeOuterJoins(associations);
		Select select = new Select( getDialect() )
			.setSelectClause(
				collectionPersister.selectFragment(alias, collectionSuffixes[0] ) +
				selectString(associations)
			)
			.setFromClause( collectionPersister.getTableName(), alias )
			.setWhereClause( whereString.toString()	)
			.setOuterJoins(
				ojf.toFromFragmentString(),
				ojf.toWhereFragmentString()
			);

		select.setOrderByClause( orderBy( associations, mergeOrderings( collectionPersister.getSQLOrderByString(alias), manyToManyOrderBy ) ) );

		if ( getFactory().getSettings().isCommentsEnabled() ) {
			select.setComment( "load collection " + collectionPersister.getRole() );
		}

		sql = select.toStatementString();
	
public java.lang.StringtoString()

		return getClass().getName() + '(" + collectionPersister.getRole() + ')";