1 package org.hibernate.loader.collection; 3 4 import java.util.ArrayList ; 5 import java.util.Arrays ; 6 import java.util.List ; 7 import java.util.Map ; 8 9 import org.hibernate.LockMode; 10 import org.hibernate.MappingException; 11 import org.hibernate.engine.SessionFactoryImplementor; 12 import org.hibernate.loader.BasicLoader; 13 import org.hibernate.loader.OuterJoinableAssociation; 14 import org.hibernate.persister.collection.QueryableCollection; 15 import org.hibernate.persister.entity.OuterJoinLoadable; 16 import org.hibernate.sql.JoinFragment; 17 import org.hibernate.sql.Select; 18 import org.hibernate.util.CollectionHelper; 19 import org.hibernate.util.StringHelper; 20 21 27 public class OneToManyJoinWalker extends CollectionJoinWalker { 28 29 private final QueryableCollection oneToManyPersister; 30 31 protected boolean isDuplicateAssociation( 32 final String foreignKeyTable, 33 final String [] foreignKeyColumns 34 ) { 35 final boolean isSameJoin = oneToManyPersister.getTableName().equals(foreignKeyTable) && 37 Arrays.equals( foreignKeyColumns, oneToManyPersister.getKeyColumnNames() ); 38 return isSameJoin || 39 super.isDuplicateAssociation(foreignKeyTable, foreignKeyColumns); 40 } 41 42 public OneToManyJoinWalker( 43 QueryableCollection oneToManyPersister, 44 int batchSize, 45 String subquery, 46 SessionFactoryImplementor factory, 47 Map enabledFilters) 48 throws MappingException { 49 50 super(subquery, factory, enabledFilters); 51 52 this.oneToManyPersister = oneToManyPersister; 53 54 final OuterJoinLoadable elementPersister = (OuterJoinLoadable) oneToManyPersister.getElementPersister(); 55 final String alias = generateRootAlias( oneToManyPersister.getRole() ); 56 57 walkEntityTree(elementPersister, alias); 58 59 List allAssociations = new ArrayList (); 60 allAssociations.addAll(associations); 61 allAssociations.add( new OuterJoinableAssociation( 62 oneToManyPersister.getCollectionType(), 63 null, 64 null, 65 alias, 66 JoinFragment.LEFT_OUTER_JOIN, 67 getFactory(), 68 CollectionHelper.EMPTY_MAP 69 ) ); 70 71 initPersisters(allAssociations, LockMode.NONE); 72 initStatementString(elementPersister, alias, batchSize, subquery); 73 74 } 75 76 private void initStatementString( 77 final OuterJoinLoadable elementPersister, 78 final String alias, 79 final int batchSize, 80 final String subquery) 81 throws MappingException { 82 83 final int joins = countEntityPersisters( associations ); 84 suffixes = BasicLoader.generateSuffixes( joins + 1 ); 85 86 final int collectionJoins = countCollectionPersisters( associations ) + 1; 87 collectionSuffixes = BasicLoader.generateSuffixes( joins + 1, collectionJoins ); 88 89 StringBuffer whereString = whereString( 90 alias, 91 oneToManyPersister.getKeyColumnNames(), 92 batchSize 93 ); 94 String filter = oneToManyPersister.filterFragment( alias, getEnabledFilters() ); 95 whereString.insert( 0, StringHelper.moveAndToBeginning(filter) ); 96 97 JoinFragment ojf = mergeOuterJoins(associations); 98 Select select = new Select( getDialect() ) 99 .setSelectClause( 100 oneToManyPersister.selectFragment(null, null, alias, suffixes[joins], collectionSuffixes[0], true) + 101 selectString(associations) 102 ) 103 .setFromClause( 104 elementPersister.fromTableFragment(alias) + 105 elementPersister.fromJoinFragment(alias, true, true) 106 ) 107 .setWhereClause( whereString.toString() ) 108 .setOuterJoins( 109 ojf.toFromFragmentString(), 110 ojf.toWhereFragmentString() + 111 elementPersister.whereJoinFragment(alias, true, true) 112 ); 113 114 select.setOrderByClause( orderBy( associations, oneToManyPersister.getSQLOrderByString(alias) ) ); 115 116 if ( getFactory().getSettings().isCommentsEnabled() ) { 117 select.setComment( "load one-to-many " + oneToManyPersister.getRole() ); 118 } 119 120 sql = select.toStatementString(); 121 } 122 123 public String toString() { 124 return getClass().getName() + '(' + oneToManyPersister.getRole() + ')'; 125 } 126 127 } 128 | Popular Tags |