KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > loader > collection > BasicCollectionJoinWalker


1 //$Id: BasicCollectionJoinWalker.java,v 1.2 2005/06/13 20:27:16 oneovthafew Exp $
2
package org.hibernate.loader.collection;
3
4 import java.util.ArrayList JavaDoc;
5 import java.util.Iterator JavaDoc;
6 import java.util.List JavaDoc;
7 import java.util.Map JavaDoc;
8 import java.util.Set JavaDoc;
9
10 import org.hibernate.FetchMode;
11 import org.hibernate.LockMode;
12 import org.hibernate.MappingException;
13 import org.hibernate.engine.SessionFactoryImplementor;
14 import org.hibernate.loader.BasicLoader;
15 import org.hibernate.loader.OuterJoinableAssociation;
16 import org.hibernate.persister.collection.QueryableCollection;
17 import org.hibernate.sql.JoinFragment;
18 import org.hibernate.sql.Select;
19 import org.hibernate.type.AssociationType;
20 import org.hibernate.util.CollectionHelper;
21 import org.hibernate.util.StringHelper;
22
23 /**
24  * Walker for collections of values and many-to-many associations
25  *
26  * @see BasicCollectionLoader
27  * @author Gavin King
28  */

29 public class BasicCollectionJoinWalker extends CollectionJoinWalker {
30     
31     private final QueryableCollection collectionPersister;
32
33     public BasicCollectionJoinWalker(
34             QueryableCollection collectionPersister,
35             int batchSize,
36             String JavaDoc subquery,
37             SessionFactoryImplementor factory,
38             Map JavaDoc enabledFilters)
39     throws MappingException {
40
41         super(subquery, factory, enabledFilters);
42
43         this.collectionPersister = collectionPersister;
44
45         String JavaDoc alias = generateRootAlias( collectionPersister.getRole() );
46
47         walkCollectionTree(collectionPersister, alias);
48
49         List JavaDoc allAssociations = new ArrayList JavaDoc();
50         allAssociations.addAll(associations);
51         allAssociations.add( new OuterJoinableAssociation(
52                 collectionPersister.getCollectionType(),
53                 null,
54                 null,
55                 alias,
56                 JoinFragment.LEFT_OUTER_JOIN,
57                 getFactory(),
58                 CollectionHelper.EMPTY_MAP
59             ) );
60
61         initPersisters(allAssociations, LockMode.NONE);
62         initStatementString(alias, batchSize, subquery);
63
64     }
65
66     private void initStatementString(
67         final String JavaDoc alias,
68         final int batchSize,
69         final String JavaDoc subquery)
70     throws MappingException {
71
72         final int joins = countEntityPersisters( associations );
73         final int collectionJoins = countCollectionPersisters( associations ) + 1;
74
75         suffixes = BasicLoader.generateSuffixes( joins );
76         collectionSuffixes = BasicLoader.generateSuffixes( joins, collectionJoins );
77
78         StringBuffer JavaDoc whereString = whereString(alias, collectionPersister.getKeyColumnNames(), batchSize);
79         String JavaDoc filter = collectionPersister.filterFragment( alias, getEnabledFilters() );
80         if ( collectionPersister.isManyToMany() ) {
81             // from the collection of associations, locate OJA for the
82
// ManyToOne corresponding to this persister to fully
83
// define the many-to-many; we need that OJA so that we can
84
// use its alias here
85
// TODO : is there a better way here?
86
Iterator JavaDoc itr = associations.iterator();
87             AssociationType associationType = ( AssociationType ) collectionPersister.getElementType();
88             while ( itr.hasNext() ) {
89                 OuterJoinableAssociation oja = ( OuterJoinableAssociation ) itr.next();
90                 if ( oja.getJoinableType() == associationType ) {
91                     // we found it
92
filter += collectionPersister.getManyToManyFilterFragment( oja.getRHSAlias(), getEnabledFilters() );
93                 }
94             }
95         }
96         whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) );
97
98         JoinFragment ojf = mergeOuterJoins(associations);
99         Select select = new Select( getDialect() )
100             .setSelectClause(
101                 collectionPersister.selectFragment(alias, collectionSuffixes[0] ) +
102                 selectString(associations)
103             )
104             .setFromClause( collectionPersister.getTableName(), alias )
105             .setWhereClause( whereString.toString() )
106             .setOuterJoins(
107                 ojf.toFromFragmentString(),
108                 ojf.toWhereFragmentString()
109             );
110
111         select.setOrderByClause( orderBy(associations, collectionPersister.getSQLOrderByString(alias) ) );
112
113         if ( getFactory().getSettings().isCommentsEnabled() ) {
114             select.setComment( "load collection " + collectionPersister.getRole() );
115         }
116
117         sql = select.toStatementString();
118     }
119
120     /**
121      * We can use an inner join for first many-to-many association
122      */

123     protected int getJoinType(
124             AssociationType type,
125             FetchMode config,
126             String JavaDoc path,
127             Set JavaDoc visitedAssociations,
128             String JavaDoc lhsTable,
129             String JavaDoc[] lhsColumns,
130             boolean nullable,
131             int currentDepth)
132     throws MappingException {
133
134         int joinType = super.getJoinType(
135                 type,
136                 config,
137                 path,
138                 lhsTable,
139                 lhsColumns,
140                 nullable,
141                 currentDepth
142         );
143         //we can use an inner join for the many-to-many
144
if ( joinType==JoinFragment.LEFT_OUTER_JOIN && "".equals(path) ) {
145             joinType=JoinFragment.INNER_JOIN;
146         }
147         return joinType;
148     }
149     
150     public String JavaDoc toString() {
151         return getClass().getName() + '(' + collectionPersister.getRole() + ')';
152     }
153
154
155 }
156
Popular Tags