001: //$Id: OneToManyJoinWalker.java 7627 2005-07-24 06:53:06Z oneovthafew $
002: package org.hibernate.loader.collection;
003:
004: import java.util.ArrayList;
005: import java.util.Arrays;
006: import java.util.List;
007: import java.util.Map;
008:
009: import org.hibernate.LockMode;
010: import org.hibernate.MappingException;
011: import org.hibernate.engine.SessionFactoryImplementor;
012: import org.hibernate.loader.BasicLoader;
013: import org.hibernate.loader.OuterJoinableAssociation;
014: import org.hibernate.persister.collection.QueryableCollection;
015: import org.hibernate.persister.entity.OuterJoinLoadable;
016: import org.hibernate.sql.JoinFragment;
017: import org.hibernate.sql.Select;
018: import org.hibernate.util.CollectionHelper;
019: import org.hibernate.util.StringHelper;
020:
021: /**
022: * Walker for one-to-many associations
023: *
024: * @see OneToManyLoader
025: * @author Gavin King
026: */
027: public class OneToManyJoinWalker extends CollectionJoinWalker {
028:
029: private final QueryableCollection oneToManyPersister;
030:
031: protected boolean isDuplicateAssociation(
032: final String foreignKeyTable,
033: final String[] foreignKeyColumns) {
034: //disable a join back to this same association
035: final boolean isSameJoin = oneToManyPersister.getTableName()
036: .equals(foreignKeyTable)
037: && Arrays.equals(foreignKeyColumns, oneToManyPersister
038: .getKeyColumnNames());
039: return isSameJoin
040: || super .isDuplicateAssociation(foreignKeyTable,
041: foreignKeyColumns);
042: }
043:
044: public OneToManyJoinWalker(QueryableCollection oneToManyPersister,
045: int batchSize, String subquery,
046: SessionFactoryImplementor factory, Map enabledFilters)
047: throws MappingException {
048:
049: super (factory, enabledFilters);
050:
051: this .oneToManyPersister = oneToManyPersister;
052:
053: final OuterJoinLoadable elementPersister = (OuterJoinLoadable) oneToManyPersister
054: .getElementPersister();
055: final String alias = generateRootAlias(oneToManyPersister
056: .getRole());
057:
058: walkEntityTree(elementPersister, alias);
059:
060: List allAssociations = new ArrayList();
061: allAssociations.addAll(associations);
062: allAssociations.add(new OuterJoinableAssociation(
063: oneToManyPersister.getCollectionType(), null, null,
064: alias, JoinFragment.LEFT_OUTER_JOIN, getFactory(),
065: CollectionHelper.EMPTY_MAP));
066:
067: initPersisters(allAssociations, LockMode.NONE);
068: initStatementString(elementPersister, alias, batchSize,
069: subquery);
070:
071: }
072:
073: private void initStatementString(
074: final OuterJoinLoadable elementPersister,
075: final String alias, final int batchSize,
076: final String subquery) throws MappingException {
077:
078: final int joins = countEntityPersisters(associations);
079: suffixes = BasicLoader.generateSuffixes(joins + 1);
080:
081: final int collectionJoins = countCollectionPersisters(associations) + 1;
082: collectionSuffixes = BasicLoader.generateSuffixes(joins + 1,
083: collectionJoins);
084:
085: StringBuffer whereString = whereString(alias,
086: oneToManyPersister.getKeyColumnNames(), subquery,
087: batchSize);
088: String filter = oneToManyPersister.filterFragment(alias,
089: getEnabledFilters());
090: whereString.insert(0, StringHelper.moveAndToBeginning(filter));
091:
092: JoinFragment ojf = mergeOuterJoins(associations);
093: Select select = new Select(getDialect()).setSelectClause(
094: oneToManyPersister.selectFragment(null, null, alias,
095: suffixes[joins], collectionSuffixes[0], true)
096: + selectString(associations)).setFromClause(
097: elementPersister.fromTableFragment(alias)
098: + elementPersister.fromJoinFragment(alias,
099: true, true)).setWhereClause(
100: whereString.toString()).setOuterJoins(
101: ojf.toFromFragmentString(),
102: ojf.toWhereFragmentString()
103: + elementPersister.whereJoinFragment(alias,
104: true, true));
105:
106: select.setOrderByClause(orderBy(associations,
107: oneToManyPersister.getSQLOrderByString(alias)));
108:
109: if (getFactory().getSettings().isCommentsEnabled()) {
110: select.setComment("load one-to-many "
111: + oneToManyPersister.getRole());
112: }
113:
114: sql = select.toStatementString();
115: }
116:
117: public String toString() {
118: return getClass().getName() + '('
119: + oneToManyPersister.getRole() + ')';
120: }
121:
122: }
|