~raginggoblin/infolog/infolog

« back to all changes in this revision

Viewing changes to InfologServer/lib/hibernate-distribution-3.3.2.GA/project/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java

  • Committer: Raging Goblin
  • Date: 2013-11-16 16:51:32 UTC
  • Revision ID: raging_goblin-20131116165132-weujnptzc88uy4ah
Mavenized the project, now using shared project InfologSync

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Hibernate, Relational Persistence for Idiomatic Java
3
 
 *
4
 
 * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
5
 
 * indicated by the @author tags or express copyright attribution
6
 
 * statements applied by the authors.  All third-party contributions are
7
 
 * distributed under license by Red Hat Middleware LLC.
8
 
 *
9
 
 * This copyrighted material is made available to anyone wishing to use, modify,
10
 
 * copy, or redistribute it subject to the terms and conditions of the GNU
11
 
 * Lesser General Public License, as published by the Free Software Foundation.
12
 
 *
13
 
 * This program is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
16
 
 * for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public License
19
 
 * along with this distribution; if not, write to:
20
 
 * Free Software Foundation, Inc.
21
 
 * 51 Franklin Street, Fifth Floor
22
 
 * Boston, MA  02110-1301  USA
23
 
 *
24
 
 */
25
 
package org.hibernate.loader.collection;
26
 
 
27
 
import java.util.ArrayList;
28
 
import java.util.Iterator;
29
 
import java.util.List;
30
 
import java.util.Map;
31
 
import java.util.Set;
32
 
 
33
 
import org.hibernate.FetchMode;
34
 
import org.hibernate.LockMode;
35
 
import org.hibernate.MappingException;
36
 
import org.hibernate.engine.SessionFactoryImplementor;
37
 
import org.hibernate.loader.BasicLoader;
38
 
import org.hibernate.loader.OuterJoinableAssociation;
39
 
import org.hibernate.persister.collection.QueryableCollection;
40
 
import org.hibernate.sql.JoinFragment;
41
 
import org.hibernate.sql.Select;
42
 
import org.hibernate.type.AssociationType;
43
 
import org.hibernate.util.CollectionHelper;
44
 
import org.hibernate.util.StringHelper;
45
 
 
46
 
/**
47
 
 * Walker for collections of values and many-to-many associations
48
 
 * 
49
 
 * @see BasicCollectionLoader
50
 
 * @author Gavin King
51
 
 */
52
 
public class BasicCollectionJoinWalker extends CollectionJoinWalker {
53
 
        
54
 
        private final QueryableCollection collectionPersister;
55
 
 
56
 
        public BasicCollectionJoinWalker(
57
 
                        QueryableCollection collectionPersister, 
58
 
                        int batchSize, 
59
 
                        String subquery, 
60
 
                        SessionFactoryImplementor factory, 
61
 
                        Map enabledFilters)
62
 
        throws MappingException {
63
 
 
64
 
                super(factory, enabledFilters);
65
 
 
66
 
                this.collectionPersister = collectionPersister;
67
 
 
68
 
                String alias = generateRootAlias( collectionPersister.getRole() );
69
 
 
70
 
                walkCollectionTree(collectionPersister, alias);
71
 
 
72
 
                List allAssociations = new ArrayList();
73
 
                allAssociations.addAll(associations);
74
 
                allAssociations.add( new OuterJoinableAssociation( 
75
 
                                collectionPersister.getCollectionType(),
76
 
                                null, 
77
 
                                null, 
78
 
                                alias, 
79
 
                                JoinFragment.LEFT_OUTER_JOIN, 
80
 
                                getFactory(), 
81
 
                                CollectionHelper.EMPTY_MAP 
82
 
                        ) );
83
 
 
84
 
                initPersisters(allAssociations, LockMode.NONE);
85
 
                initStatementString(alias, batchSize, subquery);
86
 
 
87
 
        }
88
 
 
89
 
        private void initStatementString(
90
 
                final String alias,
91
 
                final int batchSize,
92
 
                final String subquery)
93
 
        throws MappingException {
94
 
 
95
 
                final int joins = countEntityPersisters( associations );
96
 
                final int collectionJoins = countCollectionPersisters( associations ) + 1;
97
 
 
98
 
                suffixes = BasicLoader.generateSuffixes( joins );
99
 
                collectionSuffixes = BasicLoader.generateSuffixes( joins, collectionJoins );
100
 
 
101
 
                StringBuffer whereString = whereString(
102
 
                                alias, 
103
 
                                collectionPersister.getKeyColumnNames(), 
104
 
                                subquery,
105
 
                                batchSize
106
 
                        );
107
 
 
108
 
                String manyToManyOrderBy = "";
109
 
                String filter = collectionPersister.filterFragment( alias, getEnabledFilters() );
110
 
                if ( collectionPersister.isManyToMany() ) {
111
 
                        // from the collection of associations, locate OJA for the
112
 
                        // ManyToOne corresponding to this persister to fully
113
 
                        // define the many-to-many; we need that OJA so that we can
114
 
                        // use its alias here
115
 
                        // TODO : is there a better way here?
116
 
                        Iterator itr = associations.iterator();
117
 
                        AssociationType associationType = ( AssociationType ) collectionPersister.getElementType();
118
 
                        while ( itr.hasNext() ) {
119
 
                                OuterJoinableAssociation oja = ( OuterJoinableAssociation ) itr.next();
120
 
                                if ( oja.getJoinableType() == associationType ) {
121
 
                                        // we found it
122
 
                                        filter += collectionPersister.getManyToManyFilterFragment( 
123
 
                                                        oja.getRHSAlias(), 
124
 
                                                        getEnabledFilters() 
125
 
                                                );
126
 
                                                manyToManyOrderBy += collectionPersister.getManyToManyOrderByString( oja.getRHSAlias() );
127
 
                                }
128
 
                        }
129
 
                }
130
 
                whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) );
131
 
 
132
 
                JoinFragment ojf = mergeOuterJoins(associations);
133
 
                Select select = new Select( getDialect() )
134
 
                        .setSelectClause(
135
 
                                collectionPersister.selectFragment(alias, collectionSuffixes[0] ) +
136
 
                                selectString(associations)
137
 
                        )
138
 
                        .setFromClause( collectionPersister.getTableName(), alias )
139
 
                        .setWhereClause( whereString.toString() )
140
 
                        .setOuterJoins(
141
 
                                ojf.toFromFragmentString(),
142
 
                                ojf.toWhereFragmentString()
143
 
                        );
144
 
 
145
 
                select.setOrderByClause( orderBy( associations, mergeOrderings( collectionPersister.getSQLOrderByString(alias), manyToManyOrderBy ) ) );
146
 
 
147
 
                if ( getFactory().getSettings().isCommentsEnabled() ) {
148
 
                        select.setComment( "load collection " + collectionPersister.getRole() );
149
 
                }
150
 
 
151
 
                sql = select.toStatementString();
152
 
        }
153
 
 
154
 
        /**
155
 
         * We can use an inner join for first many-to-many association
156
 
         */
157
 
        protected int getJoinType(
158
 
                        AssociationType type, 
159
 
                        FetchMode config, 
160
 
                        String path, 
161
 
                        Set visitedAssociations,
162
 
                        String lhsTable,
163
 
                        String[] lhsColumns,
164
 
                        boolean nullable,
165
 
                        int currentDepth)
166
 
        throws MappingException {
167
 
 
168
 
                int joinType = super.getJoinType(
169
 
                                type, 
170
 
                                config, 
171
 
                                path, 
172
 
                                lhsTable, 
173
 
                                lhsColumns, 
174
 
                                nullable, 
175
 
                                currentDepth,
176
 
                                null
177
 
                        );
178
 
                //we can use an inner join for the many-to-many
179
 
                if ( joinType==JoinFragment.LEFT_OUTER_JOIN && "".equals(path) ) {
180
 
                        joinType=JoinFragment.INNER_JOIN;
181
 
                }
182
 
                return joinType;
183
 
        }
184
 
        
185
 
        public String toString() {
186
 
                return getClass().getName() + '(' + collectionPersister.getRole() + ')';
187
 
        }
188
 
 
189
 
 
190
 
}