Source Code Cross Referenced for SingleTableEntityPersister.java in  » Database-ORM » hibernate » org » hibernate » persister » entity » 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.persister.entity 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        //$Id: SingleTableEntityPersister.java 10040 2006-06-22 19:51:43Z steve.ebersole@jboss.com $
002:        package org.hibernate.persister.entity;
003:
004:        import java.io.Serializable;
005:        import java.util.ArrayList;
006:        import java.util.HashMap;
007:        import java.util.HashSet;
008:        import java.util.Iterator;
009:        import java.util.Map;
010:
011:        import org.hibernate.EntityMode;
012:        import org.hibernate.HibernateException;
013:        import org.hibernate.MappingException;
014:        import org.hibernate.cache.CacheConcurrencyStrategy;
015:        import org.hibernate.engine.Mapping;
016:        import org.hibernate.engine.SessionFactoryImplementor;
017:        import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
018:        import org.hibernate.mapping.Column;
019:        import org.hibernate.mapping.Formula;
020:        import org.hibernate.mapping.Join;
021:        import org.hibernate.mapping.PersistentClass;
022:        import org.hibernate.mapping.Property;
023:        import org.hibernate.mapping.Selectable;
024:        import org.hibernate.mapping.Subclass;
025:        import org.hibernate.mapping.Table;
026:        import org.hibernate.mapping.Value;
027:        import org.hibernate.sql.InFragment;
028:        import org.hibernate.sql.Insert;
029:        import org.hibernate.sql.SelectFragment;
030:        import org.hibernate.type.AssociationType;
031:        import org.hibernate.type.DiscriminatorType;
032:        import org.hibernate.type.Type;
033:        import org.hibernate.util.ArrayHelper;
034:        import org.hibernate.util.MarkerObject;
035:
036:        /**
037:         * The default implementation of the <tt>EntityPersister</tt> interface.
038:         * Implements the "table-per-class-hierarchy" or "roll-up" mapping strategy
039:         * for an entity class and its inheritence hierarchy.  This is implemented
040:         * as a single table holding all classes in the hierarchy with a discrimator
041:         * column used to determine which concrete class is referenced.
042:         *
043:         * @author Gavin King
044:         */
045:        public class SingleTableEntityPersister extends AbstractEntityPersister {
046:
047:            // the class hierarchy structure
048:            private final int joinSpan;
049:            private final String[] qualifiedTableNames;
050:            private final boolean[] isInverseTable;
051:            private final boolean[] isNullableTable;
052:            private final String[][] keyColumnNames;
053:            private final boolean[] cascadeDeleteEnabled;
054:            private final boolean hasSequentialSelects;
055:
056:            private final String[] spaces;
057:
058:            private final String[] subclassClosure;
059:
060:            private final String[] subclassTableNameClosure;
061:            private final boolean[] subclassTableIsLazyClosure;
062:            private final boolean[] isInverseSubclassTable;
063:            private final boolean[] isNullableSubclassTable;
064:            private final boolean[] subclassTableSequentialSelect;
065:            private final String[][] subclassTableKeyColumnClosure;
066:            private final boolean[] isClassOrSuperclassTable;
067:
068:            // properties of this class, including inherited properties
069:            private final int[] propertyTableNumbers;
070:
071:            // the closure of all columns used by the entire hierarchy including
072:            // subclasses and superclasses of this class
073:            private final int[] subclassPropertyTableNumberClosure;
074:
075:            private final int[] subclassColumnTableNumberClosure;
076:            private final int[] subclassFormulaTableNumberClosure;
077:
078:            // discriminator column
079:            private final Map subclassesByDiscriminatorValue = new HashMap();
080:            private final boolean forceDiscriminator;
081:            private final String discriminatorColumnName;
082:            private final String discriminatorFormula;
083:            private final String discriminatorFormulaTemplate;
084:            private final String discriminatorAlias;
085:            private final Type discriminatorType;
086:            private final String discriminatorSQLValue;
087:            private final boolean discriminatorInsertable;
088:
089:            private final String[] constraintOrderedTableNames;
090:            private final String[][] constraintOrderedKeyColumnNames;
091:
092:            //private final Map propertyTableNumbersByName = new HashMap();
093:            private final Map propertyTableNumbersByNameAndSubclass = new HashMap();
094:
095:            private final Map sequentialSelectStringsByEntityName = new HashMap();
096:
097:            private static final Object NULL_DISCRIMINATOR = new MarkerObject(
098:                    "<null discriminator>");
099:            private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject(
100:                    "<not null discriminator>");
101:
102:            //INITIALIZATION:
103:
104:            public SingleTableEntityPersister(
105:                    final PersistentClass persistentClass,
106:                    final CacheConcurrencyStrategy cache,
107:                    final SessionFactoryImplementor factory,
108:                    final Mapping mapping) throws HibernateException {
109:
110:                super (persistentClass, cache, factory);
111:
112:                // CLASS + TABLE
113:
114:                joinSpan = persistentClass.getJoinClosureSpan() + 1;
115:                qualifiedTableNames = new String[joinSpan];
116:                isInverseTable = new boolean[joinSpan];
117:                isNullableTable = new boolean[joinSpan];
118:                keyColumnNames = new String[joinSpan][];
119:                final Table table = persistentClass.getRootTable();
120:                qualifiedTableNames[0] = table.getQualifiedName(factory
121:                        .getDialect(), factory.getSettings()
122:                        .getDefaultCatalogName(), factory.getSettings()
123:                        .getDefaultSchemaName());
124:                isInverseTable[0] = false;
125:                isNullableTable[0] = false;
126:                keyColumnNames[0] = getIdentifierColumnNames();
127:                cascadeDeleteEnabled = new boolean[joinSpan];
128:
129:                // Custom sql
130:                customSQLInsert = new String[joinSpan];
131:                customSQLUpdate = new String[joinSpan];
132:                customSQLDelete = new String[joinSpan];
133:                insertCallable = new boolean[joinSpan];
134:                updateCallable = new boolean[joinSpan];
135:                deleteCallable = new boolean[joinSpan];
136:                insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
137:                updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
138:                deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
139:
140:                customSQLInsert[0] = persistentClass.getCustomSQLInsert();
141:                insertCallable[0] = customSQLInsert[0] != null
142:                        && persistentClass.isCustomInsertCallable();
143:                insertResultCheckStyles[0] = persistentClass
144:                        .getCustomSQLInsertCheckStyle() == null ? ExecuteUpdateResultCheckStyle
145:                        .determineDefault(customSQLInsert[0], insertCallable[0])
146:                        : persistentClass.getCustomSQLInsertCheckStyle();
147:                customSQLUpdate[0] = persistentClass.getCustomSQLUpdate();
148:                updateCallable[0] = customSQLUpdate[0] != null
149:                        && persistentClass.isCustomUpdateCallable();
150:                updateResultCheckStyles[0] = persistentClass
151:                        .getCustomSQLUpdateCheckStyle() == null ? ExecuteUpdateResultCheckStyle
152:                        .determineDefault(customSQLUpdate[0], updateCallable[0])
153:                        : persistentClass.getCustomSQLUpdateCheckStyle();
154:                customSQLDelete[0] = persistentClass.getCustomSQLDelete();
155:                deleteCallable[0] = customSQLDelete[0] != null
156:                        && persistentClass.isCustomDeleteCallable();
157:                deleteResultCheckStyles[0] = persistentClass
158:                        .getCustomSQLDeleteCheckStyle() == null ? ExecuteUpdateResultCheckStyle
159:                        .determineDefault(customSQLDelete[0], deleteCallable[0])
160:                        : persistentClass.getCustomSQLDeleteCheckStyle();
161:
162:                // JOINS
163:
164:                Iterator joinIter = persistentClass.getJoinClosureIterator();
165:                int j = 1;
166:                while (joinIter.hasNext()) {
167:                    Join join = (Join) joinIter.next();
168:                    qualifiedTableNames[j] = join.getTable().getQualifiedName(
169:                            factory.getDialect(),
170:                            factory.getSettings().getDefaultCatalogName(),
171:                            factory.getSettings().getDefaultSchemaName());
172:                    isInverseTable[j] = join.isInverse();
173:                    isNullableTable[j] = join.isOptional();
174:                    cascadeDeleteEnabled[j] = join.getKey()
175:                            .isCascadeDeleteEnabled()
176:                            && factory.getDialect().supportsCascadeDelete();
177:
178:                    customSQLInsert[j] = join.getCustomSQLInsert();
179:                    insertCallable[j] = customSQLInsert[j] != null
180:                            && join.isCustomInsertCallable();
181:                    insertResultCheckStyles[j] = join
182:                            .getCustomSQLInsertCheckStyle() == null ? ExecuteUpdateResultCheckStyle
183:                            .determineDefault(customSQLInsert[j],
184:                                    insertCallable[j])
185:                            : join.getCustomSQLInsertCheckStyle();
186:                    customSQLUpdate[j] = join.getCustomSQLUpdate();
187:                    updateCallable[j] = customSQLUpdate[j] != null
188:                            && join.isCustomUpdateCallable();
189:                    updateResultCheckStyles[j] = join
190:                            .getCustomSQLUpdateCheckStyle() == null ? ExecuteUpdateResultCheckStyle
191:                            .determineDefault(customSQLUpdate[j],
192:                                    updateCallable[j])
193:                            : join.getCustomSQLUpdateCheckStyle();
194:                    customSQLDelete[j] = join.getCustomSQLDelete();
195:                    deleteCallable[j] = customSQLDelete[j] != null
196:                            && join.isCustomDeleteCallable();
197:                    deleteResultCheckStyles[j] = join
198:                            .getCustomSQLDeleteCheckStyle() == null ? ExecuteUpdateResultCheckStyle
199:                            .determineDefault(customSQLDelete[j],
200:                                    deleteCallable[j])
201:                            : join.getCustomSQLDeleteCheckStyle();
202:
203:                    Iterator iter = join.getKey().getColumnIterator();
204:                    keyColumnNames[j] = new String[join.getKey()
205:                            .getColumnSpan()];
206:                    int i = 0;
207:                    while (iter.hasNext()) {
208:                        Column col = (Column) iter.next();
209:                        keyColumnNames[j][i++] = col.getQuotedName(factory
210:                                .getDialect());
211:                    }
212:
213:                    j++;
214:                }
215:
216:                constraintOrderedTableNames = new String[qualifiedTableNames.length];
217:                constraintOrderedKeyColumnNames = new String[qualifiedTableNames.length][];
218:                for (int i = qualifiedTableNames.length - 1, position = 0; i >= 0; i--, position++) {
219:                    constraintOrderedTableNames[position] = qualifiedTableNames[i];
220:                    constraintOrderedKeyColumnNames[position] = keyColumnNames[i];
221:                }
222:
223:                spaces = ArrayHelper
224:                        .join(qualifiedTableNames, ArrayHelper
225:                                .toStringArray(persistentClass
226:                                        .getSynchronizedTables()));
227:
228:                final boolean lazyAvailable = isInstrumented(EntityMode.POJO);
229:
230:                boolean hasDeferred = false;
231:                ArrayList subclassTables = new ArrayList();
232:                ArrayList joinKeyColumns = new ArrayList();
233:                ArrayList isConcretes = new ArrayList();
234:                ArrayList isDeferreds = new ArrayList();
235:                ArrayList isInverses = new ArrayList();
236:                ArrayList isNullables = new ArrayList();
237:                ArrayList isLazies = new ArrayList();
238:                subclassTables.add(qualifiedTableNames[0]);
239:                joinKeyColumns.add(getIdentifierColumnNames());
240:                isConcretes.add(Boolean.TRUE);
241:                isDeferreds.add(Boolean.FALSE);
242:                isInverses.add(Boolean.FALSE);
243:                isNullables.add(Boolean.FALSE);
244:                isLazies.add(Boolean.FALSE);
245:                joinIter = persistentClass.getSubclassJoinClosureIterator();
246:                while (joinIter.hasNext()) {
247:                    Join join = (Join) joinIter.next();
248:                    isConcretes.add(new Boolean(persistentClass
249:                            .isClassOrSuperclassJoin(join)));
250:                    isDeferreds.add(new Boolean(join.isSequentialSelect()));
251:                    isInverses.add(new Boolean(join.isInverse()));
252:                    isNullables.add(new Boolean(join.isOptional()));
253:                    isLazies.add(new Boolean(lazyAvailable && join.isLazy()));
254:                    if (join.isSequentialSelect()
255:                            && !persistentClass.isClassOrSuperclassJoin(join))
256:                        hasDeferred = true;
257:                    subclassTables.add(join.getTable().getQualifiedName(
258:                            factory.getDialect(),
259:                            factory.getSettings().getDefaultCatalogName(),
260:                            factory.getSettings().getDefaultSchemaName()));
261:                    Iterator iter = join.getKey().getColumnIterator();
262:                    String[] keyCols = new String[join.getKey().getColumnSpan()];
263:                    int i = 0;
264:                    while (iter.hasNext()) {
265:                        Column col = (Column) iter.next();
266:                        keyCols[i++] = col.getQuotedName(factory.getDialect());
267:                    }
268:                    joinKeyColumns.add(keyCols);
269:                }
270:
271:                subclassTableSequentialSelect = ArrayHelper
272:                        .toBooleanArray(isDeferreds);
273:                subclassTableNameClosure = ArrayHelper
274:                        .toStringArray(subclassTables);
275:                subclassTableIsLazyClosure = ArrayHelper
276:                        .toBooleanArray(isLazies);
277:                subclassTableKeyColumnClosure = ArrayHelper
278:                        .to2DStringArray(joinKeyColumns);
279:                isClassOrSuperclassTable = ArrayHelper
280:                        .toBooleanArray(isConcretes);
281:                isInverseSubclassTable = ArrayHelper.toBooleanArray(isInverses);
282:                isNullableSubclassTable = ArrayHelper
283:                        .toBooleanArray(isNullables);
284:                hasSequentialSelects = hasDeferred;
285:
286:                // DISCRIMINATOR
287:
288:                final Object discriminatorValue;
289:                if (persistentClass.isPolymorphic()) {
290:                    Value discrimValue = persistentClass.getDiscriminator();
291:                    if (discrimValue == null) {
292:                        throw new MappingException(
293:                                "discriminator mapping required for single table polymorphic persistence");
294:                    }
295:                    forceDiscriminator = persistentClass.isForceDiscriminator();
296:                    Selectable selectable = (Selectable) discrimValue
297:                            .getColumnIterator().next();
298:                    if (discrimValue.hasFormula()) {
299:                        Formula formula = (Formula) selectable;
300:                        discriminatorFormula = formula.getFormula();
301:                        discriminatorFormulaTemplate = formula.getTemplate(
302:                                factory.getDialect(), factory
303:                                        .getSqlFunctionRegistry());
304:                        discriminatorColumnName = null;
305:                        discriminatorAlias = "clazz_";
306:                    } else {
307:                        Column column = (Column) selectable;
308:                        discriminatorColumnName = column.getQuotedName(factory
309:                                .getDialect());
310:                        discriminatorAlias = column.getAlias(factory
311:                                .getDialect(), persistentClass.getRootTable());
312:                        discriminatorFormula = null;
313:                        discriminatorFormulaTemplate = null;
314:                    }
315:                    discriminatorType = persistentClass.getDiscriminator()
316:                            .getType();
317:                    if (persistentClass.isDiscriminatorValueNull()) {
318:                        discriminatorValue = NULL_DISCRIMINATOR;
319:                        discriminatorSQLValue = InFragment.NULL;
320:                        discriminatorInsertable = false;
321:                    } else if (persistentClass.isDiscriminatorValueNotNull()) {
322:                        discriminatorValue = NOT_NULL_DISCRIMINATOR;
323:                        discriminatorSQLValue = InFragment.NOT_NULL;
324:                        discriminatorInsertable = false;
325:                    } else {
326:                        discriminatorInsertable = persistentClass
327:                                .isDiscriminatorInsertable()
328:                                && !discrimValue.hasFormula();
329:                        try {
330:                            DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
331:                            discriminatorValue = dtype
332:                                    .stringToObject(persistentClass
333:                                            .getDiscriminatorValue());
334:                            discriminatorSQLValue = dtype.objectToSQLString(
335:                                    discriminatorValue, factory.getDialect());
336:                        } catch (ClassCastException cce) {
337:                            throw new MappingException(
338:                                    "Illegal discriminator type: "
339:                                            + discriminatorType.getName());
340:                        } catch (Exception e) {
341:                            throw new MappingException(
342:                                    "Could not format discriminator value to SQL string",
343:                                    e);
344:                        }
345:                    }
346:                } else {
347:                    forceDiscriminator = false;
348:                    discriminatorInsertable = false;
349:                    discriminatorColumnName = null;
350:                    discriminatorAlias = null;
351:                    discriminatorType = null;
352:                    discriminatorValue = null;
353:                    discriminatorSQLValue = null;
354:                    discriminatorFormula = null;
355:                    discriminatorFormulaTemplate = null;
356:                }
357:
358:                // PROPERTIES
359:
360:                propertyTableNumbers = new int[getPropertySpan()];
361:                Iterator iter = persistentClass.getPropertyClosureIterator();
362:                int i = 0;
363:                while (iter.hasNext()) {
364:                    Property prop = (Property) iter.next();
365:                    propertyTableNumbers[i++] = persistentClass
366:                            .getJoinNumber(prop);
367:
368:                }
369:
370:                //TODO: code duplication with JoinedSubclassEntityPersister
371:
372:                ArrayList columnJoinNumbers = new ArrayList();
373:                ArrayList formulaJoinedNumbers = new ArrayList();
374:                ArrayList propertyJoinNumbers = new ArrayList();
375:
376:                iter = persistentClass.getSubclassPropertyClosureIterator();
377:                while (iter.hasNext()) {
378:                    Property prop = (Property) iter.next();
379:                    Integer join = new Integer(persistentClass
380:                            .getJoinNumber(prop));
381:                    propertyJoinNumbers.add(join);
382:
383:                    //propertyTableNumbersByName.put( prop.getName(), join );
384:                    propertyTableNumbersByNameAndSubclass.put(prop
385:                            .getPersistentClass().getEntityName()
386:                            + '.' + prop.getName(), join);
387:
388:                    Iterator citer = prop.getColumnIterator();
389:                    while (citer.hasNext()) {
390:                        Selectable thing = (Selectable) citer.next();
391:                        if (thing.isFormula()) {
392:                            formulaJoinedNumbers.add(join);
393:                        } else {
394:                            columnJoinNumbers.add(join);
395:                        }
396:                    }
397:                }
398:                subclassColumnTableNumberClosure = ArrayHelper
399:                        .toIntArray(columnJoinNumbers);
400:                subclassFormulaTableNumberClosure = ArrayHelper
401:                        .toIntArray(formulaJoinedNumbers);
402:                subclassPropertyTableNumberClosure = ArrayHelper
403:                        .toIntArray(propertyJoinNumbers);
404:
405:                int subclassSpan = persistentClass.getSubclassSpan() + 1;
406:                subclassClosure = new String[subclassSpan];
407:                subclassClosure[0] = getEntityName();
408:                if (persistentClass.isPolymorphic()) {
409:                    subclassesByDiscriminatorValue.put(discriminatorValue,
410:                            getEntityName());
411:                }
412:
413:                // SUBCLASSES
414:                if (persistentClass.isPolymorphic()) {
415:                    iter = persistentClass.getSubclassIterator();
416:                    int k = 1;
417:                    while (iter.hasNext()) {
418:                        Subclass sc = (Subclass) iter.next();
419:                        subclassClosure[k++] = sc.getEntityName();
420:                        if (sc.isDiscriminatorValueNull()) {
421:                            subclassesByDiscriminatorValue.put(
422:                                    NULL_DISCRIMINATOR, sc.getEntityName());
423:                        } else if (sc.isDiscriminatorValueNotNull()) {
424:                            subclassesByDiscriminatorValue.put(
425:                                    NOT_NULL_DISCRIMINATOR, sc.getEntityName());
426:                        } else {
427:                            try {
428:                                DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
429:                                subclassesByDiscriminatorValue.put(dtype
430:                                        .stringToObject(sc
431:                                                .getDiscriminatorValue()), sc
432:                                        .getEntityName());
433:                            } catch (ClassCastException cce) {
434:                                throw new MappingException(
435:                                        "Illegal discriminator type: "
436:                                                + discriminatorType.getName());
437:                            } catch (Exception e) {
438:                                throw new MappingException(
439:                                        "Error parsing discriminator value", e);
440:                            }
441:                        }
442:                    }
443:                }
444:
445:                initLockers();
446:
447:                initSubclassPropertyAliasesMap(persistentClass);
448:
449:                postConstruct(mapping);
450:
451:            }
452:
453:            protected boolean isInverseTable(int j) {
454:                return isInverseTable[j];
455:            }
456:
457:            protected boolean isInverseSubclassTable(int j) {
458:                return isInverseSubclassTable[j];
459:            }
460:
461:            public String getDiscriminatorColumnName() {
462:                return discriminatorColumnName;
463:            }
464:
465:            protected String getDiscriminatorAlias() {
466:                return discriminatorAlias;
467:            }
468:
469:            protected String getDiscriminatorFormulaTemplate() {
470:                return discriminatorFormulaTemplate;
471:            }
472:
473:            public String getTableName() {
474:                return qualifiedTableNames[0];
475:            }
476:
477:            public Type getDiscriminatorType() {
478:                return discriminatorType;
479:            }
480:
481:            public String getDiscriminatorSQLValue() {
482:                return discriminatorSQLValue;
483:            }
484:
485:            public String[] getSubclassClosure() {
486:                return subclassClosure;
487:            }
488:
489:            public String getSubclassForDiscriminatorValue(Object value) {
490:                if (value == null) {
491:                    return (String) subclassesByDiscriminatorValue
492:                            .get(NULL_DISCRIMINATOR);
493:                } else {
494:                    String result = (String) subclassesByDiscriminatorValue
495:                            .get(value);
496:                    if (result == null)
497:                        result = (String) subclassesByDiscriminatorValue
498:                                .get(NOT_NULL_DISCRIMINATOR);
499:                    return result;
500:                }
501:            }
502:
503:            public Serializable[] getPropertySpaces() {
504:                return spaces;
505:            }
506:
507:            //Access cached SQL
508:
509:            protected boolean isDiscriminatorFormula() {
510:                return discriminatorColumnName == null;
511:            }
512:
513:            protected String getDiscriminatorFormula() {
514:                return discriminatorFormula;
515:            }
516:
517:            protected String getTableName(int j) {
518:                return qualifiedTableNames[j];
519:            }
520:
521:            protected String[] getKeyColumns(int j) {
522:                return keyColumnNames[j];
523:            }
524:
525:            protected boolean isTableCascadeDeleteEnabled(int j) {
526:                return cascadeDeleteEnabled[j];
527:            }
528:
529:            protected boolean isPropertyOfTable(int property, int j) {
530:                return propertyTableNumbers[property] == j;
531:            }
532:
533:            protected boolean isSubclassTableSequentialSelect(int j) {
534:                return subclassTableSequentialSelect[j]
535:                        && !isClassOrSuperclassTable[j];
536:            }
537:
538:            // Execute the SQL:
539:
540:            public String fromTableFragment(String name) {
541:                return getTableName() + ' ' + name;
542:            }
543:
544:            public String filterFragment(String alias) throws MappingException {
545:                String result = discriminatorFilterFragment(alias);
546:                if (hasWhere())
547:                    result += " and " + getSQLWhereString(alias);
548:                return result;
549:            }
550:
551:            public String oneToManyFilterFragment(String alias)
552:                    throws MappingException {
553:                return forceDiscriminator ? discriminatorFilterFragment(alias)
554:                        : "";
555:            }
556:
557:            private String discriminatorFilterFragment(String alias)
558:                    throws MappingException {
559:                if (needsDiscriminator()) {
560:                    InFragment frag = new InFragment();
561:
562:                    if (isDiscriminatorFormula()) {
563:                        frag.setFormula(alias,
564:                                getDiscriminatorFormulaTemplate());
565:                    } else {
566:                        frag.setColumn(alias, getDiscriminatorColumnName());
567:                    }
568:
569:                    String[] subclasses = getSubclassClosure();
570:                    for (int i = 0; i < subclasses.length; i++) {
571:                        final Queryable queryable = (Queryable) getFactory()
572:                                .getEntityPersister(subclasses[i]);
573:                        if (!queryable.isAbstract())
574:                            frag.addValue(queryable.getDiscriminatorSQLValue());
575:                    }
576:
577:                    StringBuffer buf = new StringBuffer(50).append(" and ")
578:                            .append(frag.toFragmentString());
579:
580:                    return buf.toString();
581:                } else {
582:                    return "";
583:                }
584:            }
585:
586:            private boolean needsDiscriminator() {
587:                return forceDiscriminator || isInherited();
588:            }
589:
590:            public String getSubclassPropertyTableName(int i) {
591:                return subclassTableNameClosure[subclassPropertyTableNumberClosure[i]];
592:            }
593:
594:            protected void addDiscriminatorToSelect(SelectFragment select,
595:                    String name, String suffix) {
596:                if (isDiscriminatorFormula()) {
597:                    select.addFormula(name, getDiscriminatorFormulaTemplate(),
598:                            getDiscriminatorAlias());
599:                } else {
600:                    select.addColumn(name, getDiscriminatorColumnName(),
601:                            getDiscriminatorAlias());
602:                }
603:            }
604:
605:            protected int[] getPropertyTableNumbersInSelect() {
606:                return propertyTableNumbers;
607:            }
608:
609:            protected int getSubclassPropertyTableNumber(int i) {
610:                return subclassPropertyTableNumberClosure[i];
611:            }
612:
613:            public int getTableSpan() {
614:                return joinSpan;
615:            }
616:
617:            protected void addDiscriminatorToInsert(Insert insert) {
618:
619:                if (discriminatorInsertable) {
620:                    insert.addColumn(getDiscriminatorColumnName(),
621:                            discriminatorSQLValue);
622:                }
623:
624:            }
625:
626:            protected int[] getSubclassColumnTableNumberClosure() {
627:                return subclassColumnTableNumberClosure;
628:            }
629:
630:            protected int[] getSubclassFormulaTableNumberClosure() {
631:                return subclassFormulaTableNumberClosure;
632:            }
633:
634:            protected int[] getPropertyTableNumbers() {
635:                return propertyTableNumbers;
636:            }
637:
638:            protected boolean isSubclassPropertyDeferred(String propertyName,
639:                    String entityName) {
640:                return hasSequentialSelects
641:                        && isSubclassTableSequentialSelect(getSubclassPropertyTableNumber(
642:                                propertyName, entityName));
643:            }
644:
645:            public boolean hasSequentialSelect() {
646:                return hasSequentialSelects;
647:            }
648:
649:            private int getSubclassPropertyTableNumber(String propertyName,
650:                    String entityName) {
651:                Type type = propertyMapping.toType(propertyName);
652:                if (type.isAssociationType()
653:                        && ((AssociationType) type).useLHSPrimaryKey())
654:                    return 0;
655:                final Integer tabnum = (Integer) propertyTableNumbersByNameAndSubclass
656:                        .get(entityName + '.' + propertyName);
657:                return tabnum == null ? 0 : tabnum.intValue();
658:            }
659:
660:            protected String getSequentialSelect(String entityName) {
661:                return (String) sequentialSelectStringsByEntityName
662:                        .get(entityName);
663:            }
664:
665:            private String generateSequentialSelect(Loadable persister) {
666:                //if ( this==persister || !hasSequentialSelects ) return null;
667:
668:                //note that this method could easily be moved up to BasicEntityPersister,
669:                //if we ever needed to reuse it from other subclasses
670:
671:                //figure out which tables need to be fetched
672:                AbstractEntityPersister subclassPersister = (AbstractEntityPersister) persister;
673:                HashSet tableNumbers = new HashSet();
674:                String[] props = subclassPersister.getPropertyNames();
675:                String[] classes = subclassPersister.getPropertySubclassNames();
676:                for (int i = 0; i < props.length; i++) {
677:                    int propTableNumber = getSubclassPropertyTableNumber(
678:                            props[i], classes[i]);
679:                    if (isSubclassTableSequentialSelect(propTableNumber)
680:                            && !isSubclassTableLazy(propTableNumber)) {
681:                        tableNumbers.add(new Integer(propTableNumber));
682:                    }
683:                }
684:                if (tableNumbers.isEmpty())
685:                    return null;
686:
687:                //figure out which columns are needed
688:                ArrayList columnNumbers = new ArrayList();
689:                final int[] columnTableNumbers = getSubclassColumnTableNumberClosure();
690:                for (int i = 0; i < getSubclassColumnClosure().length; i++) {
691:                    if (tableNumbers
692:                            .contains(new Integer(columnTableNumbers[i]))) {
693:                        columnNumbers.add(new Integer(i));
694:                    }
695:                }
696:
697:                //figure out which formulas are needed
698:                ArrayList formulaNumbers = new ArrayList();
699:                final int[] formulaTableNumbers = getSubclassColumnTableNumberClosure();
700:                for (int i = 0; i < getSubclassFormulaTemplateClosure().length; i++) {
701:                    if (tableNumbers.contains(new Integer(
702:                            formulaTableNumbers[i]))) {
703:                        formulaNumbers.add(new Integer(i));
704:                    }
705:                }
706:
707:                //render the SQL
708:                return renderSelect(ArrayHelper.toIntArray(tableNumbers),
709:                        ArrayHelper.toIntArray(columnNumbers), ArrayHelper
710:                                .toIntArray(formulaNumbers));
711:            }
712:
713:            protected String[] getSubclassTableKeyColumns(int j) {
714:                return subclassTableKeyColumnClosure[j];
715:            }
716:
717:            public String getSubclassTableName(int j) {
718:                return subclassTableNameClosure[j];
719:            }
720:
721:            public int getSubclassTableSpan() {
722:                return subclassTableNameClosure.length;
723:            }
724:
725:            protected boolean isClassOrSuperclassTable(int j) {
726:                return isClassOrSuperclassTable[j];
727:            }
728:
729:            protected boolean isSubclassTableLazy(int j) {
730:                return subclassTableIsLazyClosure[j];
731:            }
732:
733:            protected boolean isNullableTable(int j) {
734:                return isNullableTable[j];
735:            }
736:
737:            protected boolean isNullableSubclassTable(int j) {
738:                return isNullableSubclassTable[j];
739:            }
740:
741:            public String getPropertyTableName(String propertyName) {
742:                Integer index = getEntityMetamodel().getPropertyIndexOrNull(
743:                        propertyName);
744:                if (index == null)
745:                    return null;
746:                return qualifiedTableNames[propertyTableNumbers[index
747:                        .intValue()]];
748:            }
749:
750:            public void postInstantiate() {
751:                super .postInstantiate();
752:                if (hasSequentialSelects) {
753:                    String[] entityNames = getSubclassClosure();
754:                    for (int i = 1; i < entityNames.length; i++) {
755:                        Loadable loadable = (Loadable) getFactory()
756:                                .getEntityPersister(entityNames[i]);
757:                        if (!loadable.isAbstract()) { //perhaps not really necessary...
758:                            String sequentialSelect = generateSequentialSelect(loadable);
759:                            sequentialSelectStringsByEntityName.put(
760:                                    entityNames[i], sequentialSelect);
761:                        }
762:                    }
763:                }
764:            }
765:
766:            public boolean isMultiTable() {
767:                return getTableSpan() > 1;
768:            }
769:
770:            public String[] getConstraintOrderedTableNameClosure() {
771:                return constraintOrderedTableNames;
772:            }
773:
774:            public String[][] getContraintOrderedTableKeyColumnClosure() {
775:                return constraintOrderedKeyColumnNames;
776:            }
777:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.