Source Code Cross Referenced for JDBCLoadRelationCommand.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » ejb » plugins » cmp » jdbc » 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 » EJB Server JBoss 4.2.1 » server » org.jboss.ejb.plugins.cmp.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.ejb.plugins.cmp.jdbc;
023:
024:        import java.sql.Connection;
025:        import java.sql.PreparedStatement;
026:        import java.sql.ResultSet;
027:        import java.util.ArrayList;
028:        import java.util.Collection;
029:        import java.util.Iterator;
030:        import java.util.HashMap;
031:        import java.util.List;
032:        import java.util.Map;
033:        import java.util.Collections;
034:        import javax.ejb.EJBException;
035:
036:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
037:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMPFieldBridge;
038:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge;
039:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
040:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCFunctionMappingMetaData;
041:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCReadAheadMetaData;
042:        import org.jboss.logging.Logger;
043:        import org.jboss.deployment.DeploymentException;
044:
045:        /**
046:         * Loads relations for a particular entity from a relation table.
047:         *
048:         * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
049:         * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
050:         * @version $Revision: 57209 $
051:         */
052:        public final class JDBCLoadRelationCommand {
053:            private final JDBCStoreManager manager;
054:            private final JDBCEntityBridge entity;
055:            private final Logger log;
056:
057:            public JDBCLoadRelationCommand(JDBCStoreManager manager) {
058:                this .manager = manager;
059:                this .entity = (JDBCEntityBridge) manager.getEntityBridge();
060:
061:                // Create the Log
062:                log = Logger.getLogger(this .getClass().getName() + "."
063:                        + manager.getMetaData().getName());
064:            }
065:
066:            public Collection execute(JDBCCMRFieldBridge cmrField, Object pk) {
067:                JDBCCMRFieldBridge relatedCMRField = (JDBCCMRFieldBridge) cmrField
068:                        .getRelatedCMRField();
069:
070:                // get the read ahead cahces
071:                ReadAheadCache readAheadCache = manager.getReadAheadCache();
072:                ReadAheadCache relatedReadAheadCache = cmrField
073:                        .getRelatedManager().getReadAheadCache();
074:
075:                // get the finder results associated with this context, if it exists
076:                ReadAheadCache.EntityReadAheadInfo info = readAheadCache
077:                        .getEntityReadAheadInfo(pk);
078:                List loadKeys = info.getLoadKeys();
079:
080:                Connection con = null;
081:                PreparedStatement ps = null;
082:                ResultSet rs = null;
083:                try {
084:                    // generate the sql
085:                    boolean[] preloadMask = getPreloadMask(cmrField);
086:                    String sql = getSQL(cmrField, preloadMask, loadKeys.size());
087:
088:                    // create the statement
089:                    if (log.isDebugEnabled())
090:                        log.debug("load relation SQL: " + sql);
091:
092:                    // get the connection
093:                    con = cmrField.getDataSource().getConnection();
094:                    ps = con.prepareStatement(sql.toString());
095:
096:                    // Set the fetch size of the statement
097:                    if (entity.getFetchSize() > 0) {
098:                        ps.setFetchSize(entity.getFetchSize());
099:                    }
100:
101:                    // get the load fields
102:                    JDBCCMPFieldBridge[] myKeyFields = getMyKeyFields(cmrField);
103:                    JDBCCMPFieldBridge[] relatedKeyFields = getRelatedKeyFields(cmrField);
104:
105:                    // set the parameters
106:                    int paramIndex = 1;
107:                    for (int i = 0; i < loadKeys.size(); i++) {
108:                        Object key = loadKeys.get(i);
109:                        for (int j = 0; j < myKeyFields.length; ++j)
110:                            paramIndex = myKeyFields[j]
111:                                    .setPrimaryKeyParameters(ps, paramIndex,
112:                                            key);
113:                    }
114:
115:                    // execute statement
116:                    rs = ps.executeQuery();
117:
118:                    // initialize the results map
119:                    Map resultsMap = new HashMap(loadKeys.size());
120:                    for (int i = 0; i < loadKeys.size(); ++i) {
121:                        resultsMap.put(loadKeys.get(i), new ArrayList());
122:                    }
123:
124:                    // load the results
125:                    Object[] ref = new Object[1];
126:                    while (rs.next()) {
127:                        // reset the column index for this row
128:                        int index = 1;
129:
130:                        // ref must be reset to null before each load
131:                        ref[0] = null;
132:
133:                        // if we are loading more then one entity, load the pk from the row
134:                        Object loadedPk = pk;
135:                        if (loadKeys.size() > 1) {
136:                            // load the pk
137:                            for (int i = 0; i < myKeyFields.length; ++i) {
138:                                index = myKeyFields[i].loadPrimaryKeyResults(
139:                                        rs, index, ref);
140:                                if (ref[0] == null) {
141:                                    break;
142:                                }
143:                            }
144:                            loadedPk = ref[0];
145:                        }
146:
147:                        // load the fk
148:                        ref[0] = null;
149:                        for (int i = 0; i < relatedKeyFields.length; ++i) {
150:                            index = relatedKeyFields[i].loadPrimaryKeyResults(
151:                                    rs, index, ref);
152:                            if (ref[0] == null) {
153:                                break;
154:                            }
155:                        }
156:                        Object loadedFk = ref[0];
157:
158:                        if (loadedFk != null) {
159:                            // add this value to the list for loadedPk
160:                            List results = (List) resultsMap.get(loadedPk);
161:                            results.add(loadedFk);
162:
163:                            // if the related cmr field is single valued we can pre-load
164:                            // the reverse relationship
165:                            if (relatedCMRField.isSingleValued()) {
166:                                relatedReadAheadCache.addPreloadData(loadedFk,
167:                                        relatedCMRField, Collections
168:                                                .singletonList(loadedPk));
169:                            }
170:
171:                            // read the preload fields
172:                            if (preloadMask != null) {
173:                                JDBCFieldBridge[] relatedFields = cmrField
174:                                        .getRelatedJDBCEntity()
175:                                        .getTableFields();
176:                                for (int i = 0; i < relatedFields.length; ++i) {
177:                                    if (preloadMask[i]) {
178:                                        JDBCFieldBridge field = relatedFields[i];
179:                                        ref[0] = null;
180:
181:                                        // read the value and store it in the readahead cache
182:                                        index = field.loadArgumentResults(rs,
183:                                                index, ref);
184:                                        relatedReadAheadCache.addPreloadData(
185:                                                loadedFk, field, ref[0]);
186:                                    }
187:                                }
188:                            }
189:                        }
190:                    }
191:
192:                    // set all of the preloaded values
193:                    JDBCReadAheadMetaData readAhead = relatedCMRField
194:                            .getReadAhead();
195:                    for (Iterator iter = resultsMap.keySet().iterator(); iter
196:                            .hasNext();) {
197:                        Object key = iter.next();
198:
199:                        // get the results for this key
200:                        List results = (List) resultsMap.get(key);
201:
202:                        // store the results list for readahead on-load
203:                        relatedReadAheadCache.addFinderResults(results,
204:                                readAhead);
205:
206:                        // store the preloaded relationship (unless this is the realts we
207:                        // are actually after)
208:                        if (!key.equals(pk)) {
209:                            readAheadCache.addPreloadData(key, cmrField,
210:                                    results);
211:                        }
212:                    }
213:
214:                    // success, return the results
215:                    return (List) resultsMap.get(pk);
216:                } catch (EJBException e) {
217:                    throw e;
218:                } catch (Exception e) {
219:                    throw new EJBException("Load relation failed", e);
220:                } finally {
221:                    JDBCUtil.safeClose(rs);
222:                    JDBCUtil.safeClose(ps);
223:                    JDBCUtil.safeClose(con);
224:                }
225:            }
226:
227:            private String getSQL(JDBCCMRFieldBridge cmrField,
228:                    boolean[] preloadMask, int keyCount)
229:                    throws DeploymentException {
230:                JDBCCMPFieldBridge[] myKeyFields = getMyKeyFields(cmrField);
231:                JDBCCMPFieldBridge[] relatedKeyFields = getRelatedKeyFields(cmrField);
232:                String relationTable = getQualifiedRelationTable(cmrField);
233:                JDBCEntityBridge relatedEntity = cmrField
234:                        .getRelatedJDBCEntity();
235:                String relatedTable = relatedEntity.getQualifiedTableName();
236:
237:                // do we need to join the relation table and the related table
238:                boolean join = ((preloadMask != null) || cmrField
239:                        .allFkFieldsMappedToPkFields())
240:                        && (relatedKeyFields != relatedEntity
241:                                .getPrimaryKeyFields());
242:
243:                // aliases for the tables, only required if we are joining the tables
244:                String relationTableAlias;
245:                String relatedTableAlias;
246:                if (join) {
247:                    relationTableAlias = getRelationTable(cmrField);
248:                    relatedTableAlias = (relatedTable.equals(relationTable) ? getRelationTable(cmrField)
249:                            + '_' + cmrField.getFieldName()
250:                            : relatedEntity.getTableName());
251:                } else {
252:                    relationTableAlias = "";
253:                    relatedTableAlias = "";
254:                }
255:
256:                JDBCFunctionMappingMetaData selectTemplate = getSelectTemplate(cmrField);
257:                return selectTemplate == null ? getPlainSQL(keyCount,
258:                        myKeyFields, relationTableAlias, relatedKeyFields,
259:                        preloadMask, cmrField, relatedTableAlias,
260:                        relationTable, join, relatedTable) : getSQLByTemplate(
261:                        keyCount, myKeyFields, relationTableAlias,
262:                        relatedKeyFields, preloadMask, cmrField,
263:                        relatedTableAlias, relationTable, join, relatedTable,
264:                        selectTemplate);
265:            }
266:
267:            private JDBCCMPFieldBridge[] getMyKeyFields(
268:                    JDBCCMRFieldBridge cmrField) {
269:                if (cmrField.getRelationMetaData().isTableMappingStyle()) {
270:                    // relation table
271:                    return (JDBCCMPFieldBridge[]) cmrField.getTableKeyFields();
272:                } else if (cmrField.getRelatedCMRField().hasForeignKey()) {
273:                    // related has foreign key
274:                    return (JDBCCMPFieldBridge[]) cmrField.getRelatedCMRField()
275:                            .getForeignKeyFields();
276:                } else {
277:                    // i have foreign key
278:                    return (JDBCCMPFieldBridge[]) entity.getPrimaryKeyFields();
279:                }
280:            }
281:
282:            private static JDBCCMPFieldBridge[] getRelatedKeyFields(
283:                    JDBCCMRFieldBridge cmrField) {
284:                if (cmrField.getRelationMetaData().isTableMappingStyle()) {
285:                    // relation table
286:                    return (JDBCCMPFieldBridge[]) cmrField.getRelatedCMRField()
287:                            .getTableKeyFields();
288:                } else if (cmrField.getRelatedCMRField().hasForeignKey()) {
289:                    // related has foreign key
290:                    return (JDBCCMPFieldBridge[]) cmrField
291:                            .getRelatedJDBCEntity().getPrimaryKeyFields();
292:                } else {
293:                    // i have foreign key
294:                    return (JDBCCMPFieldBridge[]) cmrField
295:                            .getForeignKeyFields();
296:                }
297:            }
298:
299:            private static boolean[] getPreloadMask(JDBCCMRFieldBridge cmrField) {
300:                boolean[] preloadMask = null;
301:                if (cmrField.getReadAhead().isOnFind()) {
302:                    JDBCEntityBridge relatedEntity = cmrField
303:                            .getRelatedJDBCEntity();
304:                    String eagerLoadGroup = cmrField.getReadAhead()
305:                            .getEagerLoadGroup();
306:                    preloadMask = relatedEntity
307:                            .getLoadGroupMask(eagerLoadGroup);
308:                }
309:                return preloadMask;
310:            }
311:
312:            private String getQualifiedRelationTable(JDBCCMRFieldBridge cmrField) {
313:                if (cmrField.getRelationMetaData().isTableMappingStyle()) {
314:                    // relation table
315:                    return cmrField.getQualifiedTableName();
316:                } else if (cmrField.getRelatedCMRField().hasForeignKey()) {
317:                    // related has foreign key
318:                    return cmrField.getRelatedJDBCEntity()
319:                            .getQualifiedTableName();
320:                } else {
321:                    // i have foreign key
322:                    return entity.getQualifiedTableName();
323:                }
324:            }
325:
326:            private String getRelationTable(JDBCCMRFieldBridge cmrField) {
327:                if (cmrField.getRelationMetaData().isTableMappingStyle()) {
328:                    // relation table
329:                    return cmrField.getTableName();
330:                } else if (cmrField.getRelatedCMRField().hasForeignKey()) {
331:                    // related has foreign key
332:                    return cmrField.getRelatedJDBCEntity().getTableName();
333:                } else {
334:                    // i have foreign key
335:                    return entity.getTableName();
336:                }
337:            }
338:
339:            private JDBCFunctionMappingMetaData getSelectTemplate(
340:                    JDBCCMRFieldBridge cmrField) throws DeploymentException {
341:
342:                JDBCFunctionMappingMetaData selectTemplate = null;
343:                if (cmrField.getRelationMetaData().isTableMappingStyle()) {
344:                    // relation table
345:                    if (cmrField.getRelationMetaData().hasRowLocking()) {
346:                        selectTemplate = cmrField.getRelationMetaData()
347:                                .getTypeMapping().getRowLockingTemplate();
348:                        if (selectTemplate == null) {
349:                            throw new IllegalStateException(
350:                                    "row-locking is not allowed for this type of datastore");
351:                        }
352:                    }
353:                } else if (cmrField.getRelatedCMRField().hasForeignKey()) {
354:                    // related has foreign key
355:                    if (cmrField.getRelatedJDBCEntity().getMetaData()
356:                            .hasRowLocking()) {
357:                        selectTemplate = cmrField.getRelatedJDBCEntity()
358:                                .getMetaData().getTypeMapping()
359:                                .getRowLockingTemplate();
360:                        if (selectTemplate == null) {
361:                            throw new IllegalStateException(
362:                                    "row-locking is not allowed for this type of datastore");
363:                        }
364:                    }
365:                } else {
366:                    // i have foreign key
367:                    if (entity.getMetaData().hasRowLocking()) {
368:                        selectTemplate = entity.getMetaData().getTypeMapping()
369:                                .getRowLockingTemplate();
370:                        if (selectTemplate == null) {
371:                            throw new IllegalStateException(
372:                                    "row-locking is not allowed for this type of datastore");
373:                        }
374:                    }
375:                }
376:                return selectTemplate;
377:            }
378:
379:            private static String getPlainSQL(int keyCount,
380:                    JDBCCMPFieldBridge[] myKeyFields,
381:                    String relationTableAlias,
382:                    JDBCCMPFieldBridge[] relatedKeyFields,
383:                    boolean[] preloadMask, JDBCCMRFieldBridge cmrField,
384:                    String relatedTableAlias, String relationTable,
385:                    boolean join, String relatedTable) {
386:                //
387:                // column names clause
388:                //
389:                StringBuffer sql = new StringBuffer(400);
390:                sql.append(SQLUtil.SELECT);
391:
392:                if (keyCount > 1) {
393:                    SQLUtil.getColumnNamesClause(myKeyFields,
394:                            relationTableAlias, sql).append(SQLUtil.COMMA);
395:                }
396:                SQLUtil.getColumnNamesClause(relatedKeyFields,
397:                        relationTableAlias, sql);
398:
399:                if (preloadMask != null) {
400:                    SQLUtil.appendColumnNamesClause(cmrField
401:                            .getRelatedJDBCEntity().getTableFields(),
402:                            preloadMask, relatedTableAlias, sql);
403:                }
404:
405:                //
406:                // from clause
407:                //
408:                sql.append(SQLUtil.FROM).append(relationTable);
409:                if (join) {
410:                    sql.append(' ').append(relationTableAlias).append(
411:                            SQLUtil.COMMA).append(relatedTable).append(' ')
412:                            .append(relatedTableAlias);
413:                }
414:
415:                //
416:                // where clause
417:                //
418:                sql.append(SQLUtil.WHERE);
419:                // add the join
420:                if (join) {
421:                    // join the tables
422:                    sql.append('(');
423:                    SQLUtil.getJoinClause(
424:                            relatedKeyFields,
425:                            relationTableAlias,
426:                            cmrField.getRelatedJDBCEntity()
427:                                    .getPrimaryKeyFields(), relatedTableAlias,
428:                            sql).append(')').append(SQLUtil.AND).append('(');
429:                }
430:
431:                // add the keys
432:                String pkWhere = SQLUtil.getWhereClause(myKeyFields,
433:                        relationTableAlias, new StringBuffer(50)).toString();
434:                for (int i = 0; i < keyCount; i++) {
435:                    if (i > 0)
436:                        sql.append(SQLUtil.OR);
437:                    sql.append('(').append(pkWhere).append(')');
438:                }
439:
440:                if (join)
441:                    sql.append(')');
442:
443:                return sql.toString();
444:            }
445:
446:            private static String getSQLByTemplate(int keyCount,
447:                    JDBCCMPFieldBridge[] myKeyFields,
448:                    String relationTableAlias,
449:                    JDBCCMPFieldBridge[] relatedKeyFields,
450:                    boolean[] preloadMask, JDBCCMRFieldBridge cmrField,
451:                    String relatedTableAlias, String relationTable,
452:                    boolean join, String relatedTable,
453:                    JDBCFunctionMappingMetaData selectTemplate) {
454:                //
455:                // column names clause
456:                //
457:                StringBuffer columnNamesClause = new StringBuffer(100);
458:                if (keyCount > 1) {
459:                    SQLUtil.getColumnNamesClause(myKeyFields,
460:                            relationTableAlias, columnNamesClause).append(
461:                            SQLUtil.COMMA);
462:                }
463:                SQLUtil.getColumnNamesClause(relatedKeyFields,
464:                        relationTableAlias, columnNamesClause);
465:                if (preloadMask != null) {
466:                    SQLUtil.appendColumnNamesClause(cmrField
467:                            .getRelatedJDBCEntity().getTableFields(),
468:                            preloadMask, relatedTableAlias, columnNamesClause);
469:                }
470:
471:                //
472:                // from clause
473:                //
474:                StringBuffer fromClause = new StringBuffer(100);
475:                fromClause.append(relationTable);
476:                if (join) {
477:                    fromClause.append(' ').append(relationTableAlias).append(
478:                            SQLUtil.COMMA).append(relatedTable).append(' ')
479:                            .append(relatedTableAlias);
480:                }
481:
482:                //
483:                // where clause
484:                //
485:                StringBuffer whereClause = new StringBuffer(150);
486:                // add the join
487:                if (join) {
488:                    // join the tables
489:                    whereClause.append('(');
490:                    SQLUtil.getJoinClause(
491:                            relatedKeyFields,
492:                            relationTableAlias,
493:                            cmrField.getRelatedJDBCEntity()
494:                                    .getPrimaryKeyFields(), relatedTableAlias,
495:                            whereClause).append(')').append(SQLUtil.AND)
496:                            .append('(');
497:                }
498:
499:                // add the keys
500:                String pkWhere = SQLUtil.getWhereClause(myKeyFields,
501:                        relationTableAlias, new StringBuffer(50)).toString();
502:                for (int i = 0; i < keyCount; i++) {
503:                    if (i > 0) {
504:                        whereClause.append(SQLUtil.OR);
505:                    }
506:                    whereClause.append('(').append(pkWhere).append(')');
507:                }
508:
509:                if (join) {
510:                    whereClause.append(')');
511:                }
512:
513:                //
514:                // assemble pieces into final statement
515:                //
516:                String[] args = new String[] { columnNamesClause.toString(),
517:                        fromClause.toString(), whereClause.toString(), null // order by
518:                };
519:                return selectTemplate.getFunctionSql(args,
520:                        new StringBuffer(500)).toString();
521:            }
522:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.