Source Code Cross Referenced for QueryLoader.java in  » Database-ORM » hibernate » org » hibernate » loader » hql » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » hibernate » org.hibernate.loader.hql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // $Id: QueryLoader.java 11115 2007-01-30 14:29:39Z steve.ebersole@jboss.com $
002:        package org.hibernate.loader.hql;
003:
004:        import java.sql.PreparedStatement;
005:        import java.sql.ResultSet;
006:        import java.sql.SQLException;
007:        import java.util.HashMap;
008:        import java.util.Iterator;
009:        import java.util.List;
010:        import java.util.Map;
011:
012:        import org.hibernate.HibernateException;
013:        import org.hibernate.LockMode;
014:        import org.hibernate.QueryException;
015:        import org.hibernate.ScrollableResults;
016:        import org.hibernate.dialect.Dialect;
017:        import org.hibernate.engine.QueryParameters;
018:        import org.hibernate.engine.SessionFactoryImplementor;
019:        import org.hibernate.engine.SessionImplementor;
020:        import org.hibernate.event.EventSource;
021:        import org.hibernate.exception.JDBCExceptionHelper;
022:        import org.hibernate.hql.HolderInstantiator;
023:        import org.hibernate.hql.ast.QueryTranslatorImpl;
024:        import org.hibernate.hql.ast.tree.FromElement;
025:        import org.hibernate.hql.ast.tree.SelectClause;
026:        import org.hibernate.hql.ast.tree.QueryNode;
027:        import org.hibernate.impl.IteratorImpl;
028:        import org.hibernate.loader.BasicLoader;
029:        import org.hibernate.param.ParameterSpecification;
030:        import org.hibernate.persister.collection.CollectionPersister;
031:        import org.hibernate.persister.collection.QueryableCollection;
032:        import org.hibernate.persister.entity.Loadable;
033:        import org.hibernate.persister.entity.Queryable;
034:        import org.hibernate.persister.entity.Lockable;
035:        import org.hibernate.transform.ResultTransformer;
036:        import org.hibernate.type.EntityType;
037:        import org.hibernate.type.Type;
038:        import org.hibernate.util.ArrayHelper;
039:
040:        /**
041:         * A delegate that implements the Loader part of QueryTranslator.
042:         *
043:         * @author josh
044:         */
045:        public class QueryLoader extends BasicLoader {
046:
047:            /**
048:             * The query translator that is delegating to this object.
049:             */
050:            private QueryTranslatorImpl queryTranslator;
051:
052:            private Queryable[] entityPersisters;
053:            private String[] entityAliases;
054:            private String[] sqlAliases;
055:            private String[] sqlAliasSuffixes;
056:            private boolean[] includeInSelect;
057:
058:            private String[] collectionSuffixes;
059:
060:            private boolean hasScalars;
061:            private String[][] scalarColumnNames;
062:            //private Type[] sqlResultTypes;
063:            private Type[] queryReturnTypes;
064:
065:            private final Map sqlAliasByEntityAlias = new HashMap(8);
066:
067:            private EntityType[] ownerAssociationTypes;
068:            private int[] owners;
069:            private boolean[] entityEagerPropertyFetches;
070:
071:            private int[] collectionOwners;
072:            private QueryableCollection[] collectionPersisters;
073:
074:            private int selectLength;
075:
076:            private ResultTransformer selectNewTransformer;
077:            private String[] queryReturnAliases;
078:
079:            private LockMode[] defaultLockModes;
080:
081:            /**
082:             * Creates a new Loader implementation.
083:             *
084:             * @param queryTranslator The query translator that is the delegator.
085:             * @param factory The factory from which this loader is being created.
086:             * @param selectClause The AST representing the select clause for loading.
087:             */
088:            public QueryLoader(final QueryTranslatorImpl queryTranslator,
089:                    final SessionFactoryImplementor factory,
090:                    final SelectClause selectClause) {
091:                super (factory);
092:                this .queryTranslator = queryTranslator;
093:                initialize(selectClause);
094:                postInstantiate();
095:            }
096:
097:            private void initialize(SelectClause selectClause) {
098:
099:                List fromElementList = selectClause.getFromElementsForLoad();
100:
101:                hasScalars = selectClause.isScalarSelect();
102:                scalarColumnNames = selectClause.getColumnNames();
103:                //sqlResultTypes = selectClause.getSqlResultTypes();
104:                queryReturnTypes = selectClause.getQueryReturnTypes();
105:
106:                selectNewTransformer = HolderInstantiator
107:                        .createSelectNewTransformer(selectClause
108:                                .getConstructor(), selectClause.isMap(),
109:                                selectClause.isList());
110:                queryReturnAliases = selectClause.getQueryReturnAliases();
111:
112:                List collectionFromElements = selectClause
113:                        .getCollectionFromElements();
114:                if (collectionFromElements != null
115:                        && collectionFromElements.size() != 0) {
116:                    int length = collectionFromElements.size();
117:                    collectionPersisters = new QueryableCollection[length];
118:                    collectionOwners = new int[length];
119:                    collectionSuffixes = new String[length];
120:                    for (int i = 0; i < length; i++) {
121:                        FromElement collectionFromElement = (FromElement) collectionFromElements
122:                                .get(i);
123:                        collectionPersisters[i] = collectionFromElement
124:                                .getQueryableCollection();
125:                        collectionOwners[i] = fromElementList
126:                                .indexOf(collectionFromElement.getOrigin());
127:                        //				collectionSuffixes[i] = collectionFromElement.getColumnAliasSuffix();
128:                        //				collectionSuffixes[i] = Integer.toString( i ) + "_";
129:                        collectionSuffixes[i] = collectionFromElement
130:                                .getCollectionSuffix();
131:                    }
132:                }
133:
134:                int size = fromElementList.size();
135:                entityPersisters = new Queryable[size];
136:                entityEagerPropertyFetches = new boolean[size];
137:                entityAliases = new String[size];
138:                sqlAliases = new String[size];
139:                sqlAliasSuffixes = new String[size];
140:                includeInSelect = new boolean[size];
141:                owners = new int[size];
142:                ownerAssociationTypes = new EntityType[size];
143:
144:                for (int i = 0; i < size; i++) {
145:                    final FromElement element = (FromElement) fromElementList
146:                            .get(i);
147:                    entityPersisters[i] = (Queryable) element
148:                            .getEntityPersister();
149:
150:                    if (entityPersisters[i] == null) {
151:                        throw new IllegalStateException(
152:                                "No entity persister for " + element.toString());
153:                    }
154:
155:                    entityEagerPropertyFetches[i] = element
156:                            .isAllPropertyFetch();
157:                    sqlAliases[i] = element.getTableAlias();
158:                    entityAliases[i] = element.getClassAlias();
159:                    sqlAliasByEntityAlias.put(entityAliases[i], sqlAliases[i]);
160:                    // TODO should we just collect these like with the collections above?
161:                    sqlAliasSuffixes[i] = (size == 1) ? "" : Integer
162:                            .toString(i)
163:                            + "_";
164:                    //			sqlAliasSuffixes[i] = element.getColumnAliasSuffix();
165:                    includeInSelect[i] = !element.isFetch();
166:                    if (includeInSelect[i]) {
167:                        selectLength++;
168:                    }
169:
170:                    owners[i] = -1; //by default
171:                    if (element.isFetch()) {
172:                        if (element.isCollectionJoin()
173:                                || element.getQueryableCollection() != null) {
174:                            // This is now handled earlier in this method.
175:                        } else if (element.getDataType().isEntityType()) {
176:                            EntityType entityType = (EntityType) element
177:                                    .getDataType();
178:                            if (entityType.isOneToOne()) {
179:                                owners[i] = fromElementList.indexOf(element
180:                                        .getOrigin());
181:                            }
182:                            ownerAssociationTypes[i] = entityType;
183:                        }
184:                    }
185:                }
186:
187:                //NONE, because its the requested lock mode, not the actual!
188:                defaultLockModes = ArrayHelper.fillArray(LockMode.NONE, size);
189:
190:            }
191:
192:            // -- Loader implementation --
193:
194:            public final void validateScrollability() throws HibernateException {
195:                queryTranslator.validateScrollability();
196:            }
197:
198:            protected boolean needsFetchingScroll() {
199:                return queryTranslator.containsCollectionFetches();
200:            }
201:
202:            public Loadable[] getEntityPersisters() {
203:                return entityPersisters;
204:            }
205:
206:            public String[] getAliases() {
207:                return sqlAliases;
208:            }
209:
210:            public String[] getSqlAliasSuffixes() {
211:                return sqlAliasSuffixes;
212:            }
213:
214:            public String[] getSuffixes() {
215:                return getSqlAliasSuffixes();
216:            }
217:
218:            public String[] getCollectionSuffixes() {
219:                return collectionSuffixes;
220:            }
221:
222:            protected String getQueryIdentifier() {
223:                return queryTranslator.getQueryIdentifier();
224:            }
225:
226:            /**
227:             * The SQL query string to be called.
228:             */
229:            protected String getSQLString() {
230:                return queryTranslator.getSQLString();
231:            }
232:
233:            /**
234:             * An (optional) persister for a collection to be initialized; only collection loaders
235:             * return a non-null value
236:             */
237:            protected CollectionPersister[] getCollectionPersisters() {
238:                return collectionPersisters;
239:            }
240:
241:            protected int[] getCollectionOwners() {
242:                return collectionOwners;
243:            }
244:
245:            protected boolean[] getEntityEagerPropertyFetches() {
246:                return entityEagerPropertyFetches;
247:            }
248:
249:            /**
250:             * An array of indexes of the entity that owns a one-to-one association
251:             * to the entity at the given index (-1 if there is no "owner")
252:             */
253:            protected int[] getOwners() {
254:                return owners;
255:            }
256:
257:            protected EntityType[] getOwnerAssociationTypes() {
258:                return ownerAssociationTypes;
259:            }
260:
261:            // -- Loader overrides --
262:
263:            protected boolean isSubselectLoadingEnabled() {
264:                return hasSubselectLoadableCollections();
265:            }
266:
267:            /**
268:             * @param lockModes a collection of lock modes specified dynamically via the Query interface
269:             */
270:            protected LockMode[] getLockModes(Map lockModes) {
271:
272:                if (lockModes == null || lockModes.size() == 0) {
273:                    return defaultLockModes;
274:                } else {
275:                    // unfortunately this stuff can't be cached because
276:                    // it is per-invocation, not constant for the
277:                    // QueryTranslator instance
278:
279:                    LockMode[] lockModeArray = new LockMode[entityAliases.length];
280:                    for (int i = 0; i < entityAliases.length; i++) {
281:                        LockMode lockMode = (LockMode) lockModes
282:                                .get(entityAliases[i]);
283:                        if (lockMode == null) {
284:                            //NONE, because its the requested lock mode, not the actual!
285:                            lockMode = LockMode.NONE;
286:                        }
287:                        lockModeArray[i] = lockMode;
288:                    }
289:                    return lockModeArray;
290:                }
291:            }
292:
293:            protected String applyLocks(String sql, Map lockModes,
294:                    Dialect dialect) throws QueryException {
295:                if (lockModes == null || lockModes.size() == 0) {
296:                    return sql;
297:                }
298:
299:                // can't cache this stuff either (per-invocation)
300:                // we are given a map of user-alias -> lock mode
301:                // create a new map of sql-alias -> lock mode
302:                final Map aliasedLockModes = new HashMap();
303:                final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap()
304:                        : null;
305:                final Iterator iter = lockModes.entrySet().iterator();
306:                while (iter.hasNext()) {
307:                    Map.Entry me = (Map.Entry) iter.next();
308:                    final String userAlias = (String) me.getKey();
309:                    final String drivingSqlAlias = (String) sqlAliasByEntityAlias
310:                            .get(userAlias);
311:                    if (drivingSqlAlias == null) {
312:                        throw new IllegalArgumentException(
313:                                "could not locate alias to apply lock mode : "
314:                                        + userAlias);
315:                    }
316:                    // at this point we have (drivingSqlAlias) the SQL alias of the driving table
317:                    // corresponding to the given user alias.  However, the driving table is not
318:                    // (necessarily) the table against which we want to apply locks.  Mainly,
319:                    // the exception case here is joined-subclass hierarchies where we instead
320:                    // want to apply the lock against the root table (for all other strategies,
321:                    // it just happens that driving and root are the same).
322:                    final QueryNode select = (QueryNode) queryTranslator
323:                            .getSqlAST();
324:                    final Lockable drivingPersister = (Lockable) select
325:                            .getFromClause().getFromElement(userAlias)
326:                            .getQueryable();
327:                    final String sqlAlias = drivingPersister
328:                            .getRootTableAlias(drivingSqlAlias);
329:                    aliasedLockModes.put(sqlAlias, me.getValue());
330:                    if (keyColumnNames != null) {
331:                        keyColumnNames.put(sqlAlias, drivingPersister
332:                                .getRootTableIdentifierColumnNames());
333:                    }
334:                }
335:                return dialect.applyLocksToSql(sql, aliasedLockModes,
336:                        keyColumnNames);
337:            }
338:
339:            protected boolean upgradeLocks() {
340:                return true;
341:            }
342:
343:            private boolean hasSelectNew() {
344:                return selectNewTransformer != null;
345:            }
346:
347:            protected Object getResultColumnOrRow(Object[] row,
348:                    ResultTransformer transformer, ResultSet rs,
349:                    SessionImplementor session) throws SQLException,
350:                    HibernateException {
351:
352:                row = toResultRow(row);
353:                boolean hasTransform = hasSelectNew() || transformer != null;
354:                if (hasScalars) {
355:                    String[][] scalarColumns = scalarColumnNames;
356:                    int queryCols = queryReturnTypes.length;
357:                    if (!hasTransform && queryCols == 1) {
358:                        return queryReturnTypes[0].nullSafeGet(rs,
359:                                scalarColumns[0], session, null);
360:                    } else {
361:                        row = new Object[queryCols];
362:                        for (int i = 0; i < queryCols; i++) {
363:                            row[i] = queryReturnTypes[i].nullSafeGet(rs,
364:                                    scalarColumns[i], session, null);
365:                        }
366:                        return row;
367:                    }
368:                } else if (!hasTransform) {
369:                    return row.length == 1 ? row[0] : row;
370:                } else {
371:                    return row;
372:                }
373:
374:            }
375:
376:            protected List getResultList(List results,
377:                    ResultTransformer resultTransformer) throws QueryException {
378:                // meant to handle dynamic instantiation queries...
379:                HolderInstantiator holderInstantiator = HolderInstantiator
380:                        .getHolderInstantiator(selectNewTransformer,
381:                                resultTransformer, queryReturnAliases);
382:                if (holderInstantiator.isRequired()) {
383:                    for (int i = 0; i < results.size(); i++) {
384:                        Object[] row = (Object[]) results.get(i);
385:                        Object result = holderInstantiator.instantiate(row);
386:                        results.set(i, result);
387:                    }
388:
389:                    if (!hasSelectNew() && resultTransformer != null) {
390:                        return resultTransformer.transformList(results);
391:                    } else {
392:                        return results;
393:                    }
394:                } else {
395:                    return results;
396:                }
397:            }
398:
399:            // --- Query translator methods ---
400:
401:            public List list(SessionImplementor session,
402:                    QueryParameters queryParameters) throws HibernateException {
403:                checkQuery(queryParameters);
404:                return list(session, queryParameters, queryTranslator
405:                        .getQuerySpaces(), queryReturnTypes);
406:            }
407:
408:            private void checkQuery(QueryParameters queryParameters) {
409:                if (hasSelectNew()
410:                        && queryParameters.getResultTransformer() != null) {
411:                    throw new QueryException(
412:                            "ResultTransformer is not allowed for 'select new' queries.");
413:                }
414:            }
415:
416:            public Iterator iterate(QueryParameters queryParameters,
417:                    EventSource session) throws HibernateException {
418:                checkQuery(queryParameters);
419:                final boolean stats = session.getFactory().getStatistics()
420:                        .isStatisticsEnabled();
421:                long startTime = 0;
422:                if (stats) {
423:                    startTime = System.currentTimeMillis();
424:                }
425:
426:                try {
427:
428:                    final PreparedStatement st = prepareQueryStatement(
429:                            queryParameters, false, session);
430:
431:                    if (queryParameters.isCallable()) {
432:                        throw new QueryException(
433:                                "iterate() not supported for callable statements");
434:                    }
435:                    final ResultSet rs = getResultSet(st, queryParameters
436:                            .hasAutoDiscoverScalarTypes(), false,
437:                            queryParameters.getRowSelection(), session);
438:                    final Iterator result = new IteratorImpl(rs, st, session,
439:                            queryReturnTypes, queryTranslator.getColumnNames(),
440:                            HolderInstantiator.getHolderInstantiator(
441:                                    selectNewTransformer, queryParameters
442:                                            .getResultTransformer(),
443:                                    queryReturnAliases));
444:
445:                    if (stats) {
446:                        session.getFactory().getStatisticsImplementor()
447:                                .queryExecuted(
448:                                        //						"HQL: " + queryTranslator.getQueryString(),
449:                                        getQueryIdentifier(), 0,
450:                                        System.currentTimeMillis() - startTime);
451:                    }
452:
453:                    return result;
454:
455:                } catch (SQLException sqle) {
456:                    throw JDBCExceptionHelper.convert(getFactory()
457:                            .getSQLExceptionConverter(), sqle,
458:                            "could not execute query using iterate",
459:                            getSQLString());
460:                }
461:
462:            }
463:
464:            public ScrollableResults scroll(
465:                    final QueryParameters queryParameters,
466:                    final SessionImplementor session) throws HibernateException {
467:                checkQuery(queryParameters);
468:                return scroll(queryParameters, queryReturnTypes,
469:                        HolderInstantiator.getHolderInstantiator(
470:                                selectNewTransformer, queryParameters
471:                                        .getResultTransformer(),
472:                                queryReturnAliases), session);
473:            }
474:
475:            // -- Implementation private methods --
476:
477:            private Object[] toResultRow(Object[] row) {
478:                if (selectLength == row.length) {
479:                    return row;
480:                } else {
481:                    Object[] result = new Object[selectLength];
482:                    int j = 0;
483:                    for (int i = 0; i < row.length; i++) {
484:                        if (includeInSelect[i]) {
485:                            result[j++] = row[i];
486:                        }
487:                    }
488:                    return result;
489:                }
490:            }
491:
492:            /**
493:             * Returns the locations of all occurrences of the named parameter.
494:             */
495:            public int[] getNamedParameterLocs(String name)
496:                    throws QueryException {
497:                return queryTranslator.getParameterTranslations()
498:                        .getNamedParameterSqlLocations(name);
499:            }
500:
501:            /**
502:             * We specifically override this method here, because in general we know much more
503:             * about the parameters and their appropriate bind positions here then we do in
504:             * our super because we track them explciitly here through the ParameterSpecification
505:             * interface.
506:             *
507:             * @param queryParameters The encapsulation of the parameter values to be bound.
508:             * @param startIndex The position from which to start binding parameter values.
509:             * @param session The originating session.
510:             * @return The number of JDBC bind positions actually bound during this method execution.
511:             * @throws SQLException Indicates problems performing the binding.
512:             */
513:            protected int bindParameterValues(
514:                    final PreparedStatement statement,
515:                    final QueryParameters queryParameters,
516:                    final int startIndex, final SessionImplementor session)
517:                    throws SQLException {
518:                int position = bindFilterParameterValues(statement,
519:                        queryParameters, startIndex, session);
520:                List parameterSpecs = queryTranslator.getSqlAST().getWalker()
521:                        .getParameters();
522:                Iterator itr = parameterSpecs.iterator();
523:                while (itr.hasNext()) {
524:                    ParameterSpecification spec = (ParameterSpecification) itr
525:                            .next();
526:                    position += spec.bind(statement, queryParameters, session,
527:                            position);
528:                }
529:                return position - startIndex;
530:            }
531:
532:            private int bindFilterParameterValues(PreparedStatement st,
533:                    QueryParameters queryParameters, int position,
534:                    SessionImplementor session) throws SQLException {
535:                // todo : better to handle dynamic filters through implicit DynamicFilterParameterSpecification
536:                // see the discussion there in DynamicFilterParameterSpecification's javadocs as to why
537:                // it is currently not done that way.
538:                int filteredParamCount = queryParameters
539:                        .getFilteredPositionalParameterTypes() == null ? 0
540:                        : queryParameters.getFilteredPositionalParameterTypes().length;
541:                int nonfilteredParamCount = queryParameters
542:                        .getPositionalParameterTypes() == null ? 0
543:                        : queryParameters.getPositionalParameterTypes().length;
544:                int filterParamCount = filteredParamCount
545:                        - nonfilteredParamCount;
546:                for (int i = 0; i < filterParamCount; i++) {
547:                    Type type = queryParameters
548:                            .getFilteredPositionalParameterTypes()[i];
549:                    Object value = queryParameters
550:                            .getFilteredPositionalParameterValues()[i];
551:                    type.nullSafeSet(st, value, position, session);
552:                    position += type.getColumnSpan(getFactory());
553:                }
554:
555:                return position;
556:            }
557:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.