Source Code Cross Referenced for DatabaseQueryMechanism.java in  » Database-ORM » toplink » oracle » toplink » essentials » internal » queryframework » 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 » toplink » oracle.toplink.essentials.internal.queryframework 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         * 
0004:         * // Copyright (c) 1998, 2007, Oracle. All rights reserved.
0005:         * 
0006:         *
0007:         * The contents of this file are subject to the terms of either the GNU
0008:         * General Public License Version 2 only ("GPL") or the Common Development
0009:         * and Distribution License("CDDL") (collectively, the "License").  You
0010:         * may not use this file except in compliance with the License. You can obtain
0011:         * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
0012:         * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
0013:         * language governing permissions and limitations under the License.
0014:         * 
0015:         * When distributing the software, include this License Header Notice in each
0016:         * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
0017:         * Sun designates this particular file as subject to the "Classpath" exception
0018:         * as provided by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code.  If applicable, add the following below the License
0020:         * Header, with the fields enclosed by brackets [] replaced by your own
0021:         * identifying information: "Portions Copyrighted [year]
0022:         * [name of copyright owner]"
0023:         * 
0024:         * Contributor(s):
0025:         * 
0026:         * If you wish your version of this file to be governed by only the CDDL or
0027:         * only the GPL Version 2, indicate your decision by adding "[Contributor]
0028:         * elects to include this software in this distribution under the [CDDL or GPL
0029:         * Version 2] license."  If you don't indicate a single choice of license, a
0030:         * recipient has the option to distribute your version of this file under
0031:         * either the CDDL, the GPL Version 2 or to extend the choice of license to
0032:         * its licensees as provided above.  However, if you add GPL Version 2 code
0033:         * and therefore, elected the GPL Version 2 license, then the option applies
0034:         * only if the new code is made subject to such option by the copyright
0035:         * holder.
0036:         */
0037:        package oracle.toplink.essentials.internal.queryframework;
0038:
0039:        import java.util.*;
0040:        import java.io.*;
0041:        import oracle.toplink.essentials.internal.descriptors.OptimisticLockingPolicy;
0042:        import oracle.toplink.essentials.descriptors.VersionLockingPolicy;
0043:        import oracle.toplink.essentials.descriptors.DescriptorEvent;
0044:        import oracle.toplink.essentials.descriptors.DescriptorEventManager;
0045:        import oracle.toplink.essentials.descriptors.DescriptorQueryManager;
0046:        import oracle.toplink.essentials.internal.helper.*;
0047:        import oracle.toplink.essentials.internal.databaseaccess.*;
0048:        import oracle.toplink.essentials.internal.sessions.*;
0049:        import oracle.toplink.essentials.sessions.DatabaseRecord;
0050:        import oracle.toplink.essentials.internal.identitymaps.CacheKey;
0051:        import oracle.toplink.essentials.expressions.*;
0052:        import oracle.toplink.essentials.queryframework.*;
0053:        import oracle.toplink.essentials.exceptions.*;
0054:        import oracle.toplink.essentials.mappings.*;
0055:        import oracle.toplink.essentials.logging.SessionLog;
0056:        import oracle.toplink.essentials.internal.sessions.AbstractRecord;
0057:        import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl;
0058:        import oracle.toplink.essentials.internal.sessions.AbstractSession;
0059:        import oracle.toplink.essentials.descriptors.ClassDescriptor;
0060:
0061:        /**
0062:         * <p><b>Purpose</b>:
0063:         * Abstract class for all database query mechanism objects.
0064:         * DatabaseQueryMechanism is actually a helper class and currently is required
0065:         * for all types of queries.  Most of the work performed by the query framework is
0066:         * performed in the query mechanism.  The query mechanism contains the internal
0067:         * knowledge necessary to perform the specific database operation.
0068:         * <p>
0069:         * <p><b>Responsibilities</b>:
0070:         * Provide a common protocol for query mechanism objects.
0071:         * Provides all of the database specific work for the assigned query.
0072:         *
0073:         * @author Yvon Lavoie
0074:         * @since TOPLink/Java 1.0
0075:         */
0076:        public abstract class DatabaseQueryMechanism implements  Cloneable,
0077:                Serializable {
0078:
0079:            /** The database query that uses this mechanism. */
0080:            protected DatabaseQuery query;
0081:
0082:            /**
0083:             * Initialize the state of the query.
0084:             */
0085:            public DatabaseQueryMechanism() {
0086:            }
0087:
0088:            /**
0089:             * Initialize the state of the query
0090:             * @param query - owner of mechanism
0091:             */
0092:            public DatabaseQueryMechanism(DatabaseQuery query) {
0093:                this .query = query;
0094:            }
0095:
0096:            /**
0097:             * Remove the query object from the identity map.
0098:             */
0099:            protected void addObjectDeletedDuringCommit() {
0100:                WriteObjectQuery writeQuery = getWriteObjectQuery();
0101:                Object object = writeQuery.getObject();
0102:
0103:                // CR3510313, avoid removing aggregate collections from cache (maintain cache is false).
0104:                if (writeQuery.shouldMaintainCache()) {
0105:                    if (getSession().isUnitOfWork()) {
0106:                        ((UnitOfWorkImpl) getSession())
0107:                                .addObjectDeletedDuringCommit(object,
0108:                                        getDescriptor());
0109:                    } else {
0110:                        getSession().getIdentityMapAccessorInstance()
0111:                                .removeFromIdentityMap(
0112:                                        writeQuery.getPrimaryKey(),
0113:                                        getDescriptor().getJavaClass(),
0114:                                        getDescriptor());
0115:                    }
0116:                }
0117:            }
0118:
0119:            /**
0120:             * Add the initial write lock value to the row for insert.
0121:             */
0122:            protected void addWriteLockFieldForInsert() {
0123:                if (getDescriptor().usesOptimisticLocking()) {
0124:                    getDescriptor().getOptimisticLockingPolicy()
0125:                            .setupWriteFieldsForInsert(getWriteObjectQuery());
0126:                }
0127:            }
0128:
0129:            /**
0130:             * Internal:
0131:             * In the case of EJBQL, an expression needs to be generated. Build the required expression.
0132:             */
0133:            public void buildSelectionCriteria(AbstractSession session) {
0134:                // Default is do nothing
0135:            }
0136:
0137:            /**
0138:             * Perform a cache lookup for the query.
0139:             * If the translation row contains all the primary key fields,
0140:             * then a cache check will be performed.
0141:             * If the object is found in the cache, return it;
0142:             * otherwise return null.
0143:             */
0144:            public Object checkCacheForObject(AbstractRecord translationRow,
0145:                    AbstractSession session) {
0146:                // Null check added for CR#4295 - TW
0147:                if ((translationRow == null) || (translationRow.isEmpty())) {
0148:                    return null;
0149:                }
0150:
0151:                List keyFields = getDescriptor().getPrimaryKeyFields();
0152:                Vector primaryKey = new Vector(keyFields.size());
0153:
0154:                for (int index = 0; index < keyFields.size(); index++) {
0155:                    Object value = translationRow.get((DatabaseField) keyFields
0156:                            .get(index));
0157:                    if (value == null) {
0158:                        return null;
0159:                    } else {
0160:                        primaryKey.add(value);
0161:                    }
0162:                }
0163:                return session.getIdentityMapAccessorInstance()
0164:                        .getFromIdentityMapWithDeferredLock(primaryKey,
0165:                                getReadObjectQuery().getReferenceClass(),
0166:                                false, getDescriptor());
0167:            }
0168:
0169:            /**
0170:             * Clone the mechanism
0171:             */
0172:            protected Object clone() {
0173:                try {
0174:                    return super .clone();
0175:                } catch (CloneNotSupportedException e) {
0176:                    throw new InternalError();
0177:                }
0178:            }
0179:
0180:            /**
0181:             * Clone the mechanism for the specified query clone.
0182:             */
0183:            public DatabaseQueryMechanism clone(DatabaseQuery queryClone) {
0184:                DatabaseQueryMechanism clone = (DatabaseQueryMechanism) clone();
0185:                clone.setQuery(queryClone);
0186:                return clone;
0187:            }
0188:
0189:            /**
0190:             * Read all rows from the database using a cursored stream.
0191:             * @exception  DatabaseException - an error has occurred on the database
0192:             */
0193:            public abstract DatabaseCall cursorSelectAllRows()
0194:                    throws DatabaseException;
0195:
0196:            /**
0197:             * Delete a collection of objects
0198:             * This should be overriden by subclasses.
0199:             * @exception  DatabaseException - an error has occurred on the database
0200:             */
0201:            public boolean isEJBQLCallQueryMechanism() {
0202:                return false;
0203:            }
0204:
0205:            /**
0206:             * Build the objects for the rows, and answer them
0207:             * @exception  DatabaseException - an error has occurred on the database
0208:             */
0209:            public Object buildObjectsFromRows(Vector rows)
0210:                    throws DatabaseException {
0211:                Object result = ((ReadAllQuery) getQuery())
0212:                        .getContainerPolicy().containerInstance(rows.size());
0213:                return getDescriptor().getObjectBuilder().buildObjectsInto(
0214:                        (ReadAllQuery) getQuery(), rows, result);
0215:            };
0216:
0217:            public abstract Integer deleteAll() throws DatabaseException;
0218:
0219:            /**
0220:             * Delete an object
0221:             * This should be overriden by subclasses.
0222:             * @exception DatabaseException
0223:             * @return the row count.
0224:             */
0225:            public abstract Integer deleteObject() throws DatabaseException;
0226:
0227:            /**
0228:             * Delete an object from the database.
0229:             */
0230:            public void deleteObjectForWrite() {
0231:                WriteObjectQuery writeQuery = getWriteObjectQuery();
0232:                Object object = writeQuery.getObject();
0233:                DescriptorQueryManager queryManager = getDescriptor()
0234:                        .getQueryManager();
0235:
0236:                // check for user-defined query
0237:                if ((!writeQuery.isUserDefined())// this is not a user-defined query
0238:                        && queryManager.hasDeleteQuery()// there is a user-defined query
0239:                        && isExpressionQueryMechanism()) {// this is not a hand-coded call (custom SQL etc.)
0240:                    performUserDefinedDelete();
0241:                    return;
0242:                }
0243:
0244:                CommitManager commitManager = getSession().getCommitManager();
0245:
0246:                // This must be done after the custom query check, otherwise it will be done twice.
0247:                commitManager.markPreModifyCommitInProgress(object);
0248:
0249:                if (writeQuery.getObjectChangeSet() == null) {
0250:                    // PERF: Avoid events if no listeners.
0251:                    if (getDescriptor().getEventManager()
0252:                            .hasAnyEventListeners()) {
0253:                        // only throw the events if there is no changeset otherwise the event will be thrown twice
0254:                        // once by the calculate changes code and here
0255:                        getDescriptor().getEventManager().executeEvent(
0256:                                new DescriptorEvent(
0257:                                        DescriptorEventManager.PreDeleteEvent,
0258:                                        writeQuery));
0259:                    }
0260:                }
0261:
0262:                // check whether deep shallow modify is turned on
0263:                if (writeQuery.shouldCascadeParts()) {
0264:                    queryManager.preDelete(writeQuery);
0265:                }
0266:
0267:                // In a unit of work/writeObjects the preDelete may cause a shallow update of this object,
0268:                // in this case the following second write must do the real delete.
0269:                if (!commitManager.isShallowCommitted(object)
0270:                        && !writeQuery.shouldCascadeParts()) {
0271:                    updateForeignKeyFieldBeforeDelete();
0272:                } else {
0273:                    // CR#2660080 missing aboutToDelete event.		
0274:                    // PERF: Avoid events if no listeners.
0275:                    if (getDescriptor().getEventManager()
0276:                            .hasAnyEventListeners()) {
0277:                        DescriptorEvent event = new DescriptorEvent(
0278:                                DescriptorEventManager.AboutToDeleteEvent,
0279:                                writeQuery);
0280:                        event.setRecord(getModifyRow());
0281:                        getDescriptor().getEventManager().executeEvent(event);
0282:                    }
0283:
0284:                    int rowCount = deleteObject().intValue();
0285:
0286:                    if (rowCount < 1) {
0287:                        getSession().getEventManager().noRowsModified(
0288:                                writeQuery, object);
0289:                    }
0290:
0291:                    if (getDescriptor().usesOptimisticLocking()) {
0292:                        getDescriptor().getOptimisticLockingPolicy()
0293:                                .validateDelete(rowCount, object, writeQuery);
0294:                    }
0295:
0296:                    // remember that the object was deleted
0297:                    addObjectDeletedDuringCommit();
0298:                }
0299:
0300:                commitManager.markPostModifyCommitInProgress(object);
0301:
0302:                // Verify if deep shallow modify is turned on.
0303:                if (writeQuery.shouldCascadeParts()) {
0304:                    queryManager.postDelete(writeQuery);
0305:                }
0306:
0307:                // PERF: Avoid events if no listeners.
0308:                if (getDescriptor().getEventManager().hasAnyEventListeners()) {
0309:                    getDescriptor().getEventManager().executeEvent(
0310:                            new DescriptorEvent(
0311:                                    DescriptorEventManager.PostDeleteEvent,
0312:                                    writeQuery));
0313:                }
0314:            }
0315:
0316:            /**
0317:             * Execute a non selecting SQL call
0318:             * This should be overriden by subclasses.
0319:             * @exception DatabaseException
0320:             * @return the row count.
0321:             */
0322:            public abstract Integer executeNoSelect() throws DatabaseException;
0323:
0324:            /**
0325:             * Execute a select SQL call and return the rows.
0326:             * This should be overriden by subclasses.
0327:             * @exception DatabaseException
0328:             */
0329:            public abstract Vector executeSelect() throws DatabaseException;
0330:
0331:            /**
0332:             * Check whether the object already exists on the database; then
0333:             * perform an insert, update or delete, as appropriate.
0334:             * This method was moved here, from WriteObjectQuery.execute(),
0335:             * so we can hide the source.
0336:             * Return the object being written.
0337:             */
0338:            public Object executeWrite() throws DatabaseException,
0339:                    OptimisticLockException {
0340:                WriteObjectQuery writeQuery = getWriteObjectQuery();
0341:                Object object = writeQuery.getObject();
0342:                CommitManager commitManager = getSession().getCommitManager();
0343:
0344:                // if the object has already been committed, no work is required
0345:                if (commitManager.isCommitCompleted(object)
0346:                        || commitManager.isCommitInPostModify(object)) {
0347:                    return object;
0348:                }
0349:
0350:                // check whether the object is already being committed -
0351:                // if it is, then a shallow write must be executed
0352:                if (commitManager.isCommitInPreModify(object)) {
0353:                    writeQuery.executeShallowWrite();
0354:                    return object;
0355:                }
0356:
0357:                try {
0358:                    getSession().beginTransaction();
0359:
0360:                    if (writeQuery.getObjectChangeSet() == null) {
0361:                        // PERF: Avoid events if no listeners.
0362:                        if (getDescriptor().getEventManager()
0363:                                .hasAnyEventListeners()) {
0364:                            // only throw the events if there is no changeset otherwise the event will be thrown twice
0365:                            // once by the calculate changes code and here
0366:                            getDescriptor()
0367:                                    .getEventManager()
0368:                                    .executeEvent(
0369:                                            new DescriptorEvent(
0370:                                                    DescriptorEventManager.PreWriteEvent,
0371:                                                    writeQuery));
0372:                        }
0373:                    }
0374:                    writeQuery.executeCommit();
0375:
0376:                    // PERF: Avoid events if no listeners.
0377:                    if (getDescriptor().getEventManager()
0378:                            .hasAnyEventListeners()) {
0379:                        getDescriptor().getEventManager().executeEvent(
0380:                                new DescriptorEvent(
0381:                                        DescriptorEventManager.PostWriteEvent,
0382:                                        writeQuery));
0383:                    }
0384:
0385:                    getSession().commitTransaction();
0386:
0387:                    // notify the commit manager of the completion to the commit
0388:                    commitManager.markCommitCompleted(object);
0389:
0390:                    return object;
0391:
0392:                } catch (RuntimeException exception) {
0393:                    getSession().rollbackTransaction();
0394:                    commitManager.markCommitCompleted(object);
0395:                    throw exception;
0396:                }
0397:            }
0398:
0399:            /**
0400:             * Check whether the object already exists on the database; then
0401:             * perform an insert or update, as appropriate.
0402:             * This method was moved here, from WriteObjectQuery.execute(),
0403:             * so we can hide the source.
0404:             * Return the object being written.
0405:             */
0406:            public Object executeWriteWithChangeSet() throws DatabaseException,
0407:                    OptimisticLockException {
0408:                WriteObjectQuery writeQuery = getWriteObjectQuery();
0409:                ObjectChangeSet objectChangeSet = writeQuery
0410:                        .getObjectChangeSet();
0411:                CommitManager commitManager = getSession().getCommitManager();
0412:
0413:                //if there are no changes then there is no work required
0414:                // Check for forcedUpdate Version and Optimistic read lock (hasForcedChanges() set in ObjectChangePolicy)
0415:                if (!objectChangeSet.hasChanges()
0416:                        && !objectChangeSet.hasForcedChanges()) {
0417:                    commitManager.markCommitCompleted(objectChangeSet);
0418:                    commitManager.markCommitCompleted(writeQuery.getObject());
0419:                    return writeQuery.getObject();
0420:                }
0421:                // if the object has already been committed, no work is required
0422:                if (commitManager.isCommitCompleted(objectChangeSet)
0423:                        || commitManager.isCommitInPostModify(objectChangeSet)) {
0424:                    return writeQuery.getObject();
0425:                }
0426:
0427:                // if the object has already been committed, no work is required
0428:                // need to check for the object to ensure insert wasn't completed already.
0429:                if (commitManager.isCommitCompleted(writeQuery.getObject())
0430:                        || commitManager.isCommitInPostModify(writeQuery
0431:                                .getObject())) {
0432:                    return writeQuery.getObject();
0433:                }
0434:                try {
0435:                    getSession().beginTransaction();
0436:
0437:                    writeQuery.executeCommitWithChangeSet();
0438:
0439:                    // PERF: Avoid events if no listeners.
0440:                    if (getDescriptor().getEventManager()
0441:                            .hasAnyEventListeners()) {
0442:                        getDescriptor().getEventManager().executeEvent(
0443:                                new DescriptorEvent(
0444:                                        DescriptorEventManager.PostWriteEvent,
0445:                                        writeQuery));
0446:                    }
0447:
0448:                    getSession().commitTransaction();
0449:
0450:                    // notify the commit manager of the completion to the commit
0451:                    commitManager.markCommitCompleted(objectChangeSet);
0452:                    commitManager.markCommitCompleted(writeQuery.getObject());
0453:
0454:                    return writeQuery.getObject();
0455:
0456:                } catch (RuntimeException exception) {
0457:                    getSession().rollbackTransaction();
0458:                    commitManager.markCommitCompleted(objectChangeSet);
0459:                    commitManager.markCommitCompleted(writeQuery.getObject());
0460:                    throw exception;
0461:                }
0462:            }
0463:
0464:            /**
0465:             * Convenience method
0466:             */
0467:            protected ClassDescriptor getDescriptor() {
0468:                return getQuery().getDescriptor();
0469:            }
0470:
0471:            /**
0472:             * Convenience method
0473:             */
0474:            public AbstractRecord getModifyRow() {
0475:                if (getQuery().isModifyQuery()) {
0476:                    return ((ModifyQuery) getQuery()).getModifyRow();
0477:                } else {
0478:                    return null;
0479:                }
0480:            }
0481:
0482:            /**
0483:             * Return the query that uses the mechanism.
0484:             */
0485:            public DatabaseQuery getQuery() {
0486:                return query;
0487:            }
0488:
0489:            /**
0490:             * Convenience method
0491:             */
0492:            protected ReadObjectQuery getReadObjectQuery() {
0493:                return (ReadObjectQuery) getQuery();
0494:            }
0495:
0496:            /**
0497:             * Return the selection criteria for the mechanism.
0498:             * By default this is null. This method exists because both statement and expression
0499:             * mechanisms use an expression and some code in the mappings depends on returning this.
0500:             */
0501:            public Expression getSelectionCriteria() {
0502:                return null;
0503:            }
0504:
0505:            /**
0506:             * Convenience method
0507:             */
0508:            protected AbstractSession getSession() {
0509:                return getQuery().getSession();
0510:            }
0511:
0512:            /**
0513:             * Convenience method
0514:             */
0515:            protected AbstractRecord getTranslationRow() {
0516:                return getQuery().getTranslationRow();
0517:            }
0518:
0519:            /**
0520:             * Convenience method
0521:             */
0522:            protected WriteObjectQuery getWriteObjectQuery() {
0523:                return (WriteObjectQuery) getQuery();
0524:            }
0525:
0526:            /**
0527:             * Insert an object.
0528:             */
0529:            public abstract void insertObject() throws DatabaseException;
0530:
0531:            /**
0532:             *  Insert an object and provide the opportunity to reprepare prior to the insert.
0533:             *  This will be overridden
0534:             *  CR#3237
0535:             */
0536:            public void insertObject(boolean reprepare) {
0537:                insertObject();
0538:            }
0539:
0540:            /**
0541:             * Insert an object in the database.
0542:             */
0543:            public void insertObjectForWrite() {
0544:                WriteObjectQuery writeQuery = getWriteObjectQuery();
0545:                Object object = writeQuery.getObject();
0546:                DescriptorQueryManager queryManager = getDescriptor()
0547:                        .getQueryManager();
0548:
0549:                // check for user-defined query
0550:                if ((!writeQuery.isUserDefined())// this is not a user-defined query
0551:                        && queryManager.hasInsertQuery()// there is a user-defined query
0552:                        && isExpressionQueryMechanism()) {// this is not a hand-coded call (custom SQL etc.)
0553:                    performUserDefinedInsert();
0554:                    return;
0555:                }
0556:
0557:                CommitManager commitManager = getSession().getCommitManager();
0558:
0559:                // This must be done after the custom query check, otherwise it will be done twice.
0560:                commitManager.markPreModifyCommitInProgress(object);
0561:
0562:                if (writeQuery.getObjectChangeSet() == null) {
0563:                    // PERF: Avoid events if no listeners.
0564:                    if (getDescriptor().getEventManager()
0565:                            .hasAnyEventListeners()) {
0566:                        // only throw the events if there is no changeset otherwise the event will be thrown twice
0567:                        // once by the calculate changes code and here
0568:                        getDescriptor().getEventManager().executeEvent(
0569:                                new DescriptorEvent(
0570:                                        DescriptorEventManager.PreInsertEvent,
0571:                                        writeQuery));
0572:                    }
0573:                }
0574:
0575:                // check whether deep shallow modify is turned on
0576:                if (writeQuery.shouldCascadeParts()) {
0577:                    queryManager.preInsert(writeQuery);
0578:                }
0579:
0580:                // In a unit of work/writeObjects the preInsert may have caused a shallow insert of this object,
0581:                // in this case this second write must do an update.
0582:                if (commitManager.isShallowCommitted(object)) {
0583:                    updateForeignKeyFieldAfterInsert();
0584:                } else {
0585:                    AbstractRecord modifyRow = writeQuery.getModifyRow();
0586:                    if (modifyRow == null) {// Maybe have been passed in as in aggregate collection.
0587:                        if (writeQuery.shouldCascadeParts()) {
0588:                            writeQuery.setModifyRow(getDescriptor()
0589:                                    .getObjectBuilder().buildRow(object,
0590:                                            getSession()));
0591:                        } else {
0592:                            writeQuery.setModifyRow(getDescriptor()
0593:                                    .getObjectBuilder()
0594:                                    .buildRowForShallowInsert(object,
0595:                                            getSession()));
0596:                        }
0597:                    } else {
0598:                        if (writeQuery.shouldCascadeParts()) {
0599:                            writeQuery.setModifyRow(getDescriptor()
0600:                                    .getObjectBuilder().buildRow(modifyRow,
0601:                                            object, getSession()));
0602:                        } else {
0603:                            writeQuery.setModifyRow(getDescriptor()
0604:                                    .getObjectBuilder()
0605:                                    .buildRowForShallowInsert(modifyRow,
0606:                                            object, getSession()));
0607:                        }
0608:                    }
0609:
0610:                    // the modify row and the translation row are the same for insert
0611:                    writeQuery.setTranslationRow(getModifyRow());
0612:                    if (!writeQuery.getDescriptor()
0613:                            .isAggregateCollectionDescriptor()) {// Should/cannot be recomputed in aggregate collection.
0614:                        writeQuery.setPrimaryKey(getDescriptor()
0615:                                .getObjectBuilder()
0616:                                .extractPrimaryKeyFromObject(object,
0617:                                        getSession()));
0618:                    }
0619:                    addWriteLockFieldForInsert();
0620:
0621:                    // CR#3237
0622:                    // Store the size of the modify row so we can determine if the user has added to the row in the insert.
0623:                    int modifyRowSize = getModifyRow().size();
0624:
0625:                    // PERF: Avoid events if no listeners.
0626:                    if (getDescriptor().getEventManager()
0627:                            .hasAnyEventListeners()) {
0628:                        DescriptorEvent event = new DescriptorEvent(
0629:                                DescriptorEventManager.AboutToInsertEvent,
0630:                                writeQuery);
0631:                        event.setRecord(getModifyRow());
0632:                        getDescriptor().getEventManager().executeEvent(event);
0633:                    }
0634:
0635:                    // CR#3237
0636:                    // Call insert with a boolean that tells it to reprepare if the user has altered the modify row.
0637:                    insertObject(modifyRowSize != getModifyRow().size());
0638:
0639:                    // register the object before post insert to resolve possible cycles
0640:                    registerObjectInIdentityMap();
0641:                    if (writeQuery.getObjectChangeSet() != null) {
0642:                        //make sure that we put this new changeset in the changes list of the 
0643:                        //uow changeset for serialization, or customer usage.
0644:                        ((UnitOfWorkChangeSet) writeQuery.getObjectChangeSet()
0645:                                .getUOWChangeSet()).putNewObjectInChangesList(
0646:                                writeQuery.getObjectChangeSet(), getSession());
0647:                    }
0648:                }
0649:
0650:                commitManager.markPostModifyCommitInProgress(object);
0651:                // Verify if deep shallow modify is turned on.
0652:                if (writeQuery.shouldCascadeParts()) {
0653:                    queryManager.postInsert(writeQuery);
0654:                }
0655:
0656:                // PERF: Avoid events if no listeners.
0657:                if (getDescriptor().getEventManager().hasAnyEventListeners()) {
0658:                    getDescriptor().getEventManager().executeEvent(
0659:                            new DescriptorEvent(
0660:                                    DescriptorEventManager.PostInsertEvent,
0661:                                    writeQuery));
0662:                }
0663:            }
0664:
0665:            /**
0666:             * Insert an object in the database.
0667:             */
0668:            public void insertObjectForWriteWithChangeSet() {
0669:                WriteObjectQuery writeQuery = getWriteObjectQuery();
0670:                ObjectChangeSet objectChangeSet = writeQuery
0671:                        .getObjectChangeSet();
0672:                DescriptorQueryManager queryManager = getDescriptor()
0673:                        .getQueryManager();
0674:                CommitManager commitManager = getSession().getCommitManager();
0675:
0676:                // check for user-defined query
0677:                if ((!writeQuery.isUserDefined())// this is not a user-defined query
0678:                        && queryManager.hasInsertQuery()// there is a user-defined query
0679:                        && isExpressionQueryMechanism()) {// this is not a hand-coded call (custom SQL etc.)
0680:                    //must mark the changeSet here because the userDefined Insert will not use the changesets
0681:                    commitManager
0682:                            .markPreModifyCommitInProgress(objectChangeSet);
0683:                    performUserDefinedInsert();
0684:                    return;
0685:                }
0686:
0687:                // This must be done after the custom query check, otherwise it will be done twice.
0688:                commitManager.markPreModifyCommitInProgress(objectChangeSet);
0689:                commitManager.markPreModifyCommitInProgress(writeQuery
0690:                        .getObject());
0691:
0692:                // check whether deep shallow modify is turned on
0693:                if (writeQuery.shouldCascadeParts()) {
0694:                    queryManager.preInsert(writeQuery);
0695:                }
0696:
0697:                // In a unit of work/writeObjects the preInsert may have caused a shallow insert of this object,
0698:                // in this case this second write must do an update.
0699:                if (commitManager.isShallowCommitted(objectChangeSet)) {
0700:                    updateForeignKeyFieldAfterInsert();
0701:                } else {
0702:                    AbstractRecord modifyRow = writeQuery.getModifyRow();
0703:                    if (modifyRow == null) {// Maybe have been passed in as in aggregate collection.
0704:                        if (writeQuery.shouldCascadeParts()) {
0705:                            writeQuery.setModifyRow(getDescriptor()
0706:                                    .getObjectBuilder().buildRowWithChangeSet(
0707:                                            objectChangeSet, getSession()));
0708:                        } else {
0709:                            writeQuery.setModifyRow(getDescriptor()
0710:                                    .getObjectBuilder()
0711:                                    .buildRowForShallowInsertWithChangeSet(
0712:                                            objectChangeSet, getSession()));
0713:                        }
0714:                    } else {
0715:                        if (writeQuery.shouldCascadeParts()) {
0716:                            writeQuery.setModifyRow(getDescriptor()
0717:                                    .getObjectBuilder().buildRowWithChangeSet(
0718:                                            modifyRow, objectChangeSet,
0719:                                            getSession()));
0720:                        } else {
0721:                            writeQuery.setModifyRow(getDescriptor()
0722:                                    .getObjectBuilder()
0723:                                    .buildRowForShallowInsertWithChangeSet(
0724:                                            modifyRow, objectChangeSet,
0725:                                            getSession()));
0726:                        }
0727:                    }
0728:
0729:                    // the modify row and the translation row are the same for insert
0730:                    writeQuery.setTranslationRow(getModifyRow());
0731:                    if (!writeQuery.getDescriptor()
0732:                            .isAggregateCollectionDescriptor()) {// Should/cannot be recomputed in aggregate collection.
0733:                        writeQuery.setPrimaryKey(objectChangeSet
0734:                                .getPrimaryKeys());
0735:                    }
0736:                    addWriteLockFieldForInsert();
0737:
0738:                    // PERF: Avoid events if no listeners.
0739:                    if (getDescriptor().getEventManager()
0740:                            .hasAnyEventListeners()) {
0741:                        DescriptorEvent event = new DescriptorEvent(
0742:                                DescriptorEventManager.AboutToInsertEvent,
0743:                                writeQuery);
0744:                        event.setRecord(getModifyRow());
0745:                        getDescriptor().getEventManager().executeEvent(event);
0746:                    }
0747:
0748:                    insertObject();
0749:
0750:                    // register the object before post insert to resolve possible cycles
0751:                    registerObjectInIdentityMap();
0752:                    if (objectChangeSet != null) {
0753:                        //make sure that we put this new changeset in the changes list of the 
0754:                        //uow changeset for serialization, or customer usage.
0755:                        ((UnitOfWorkChangeSet) objectChangeSet
0756:                                .getUOWChangeSet()).putNewObjectInChangesList(
0757:                                objectChangeSet, getSession());
0758:                    }
0759:                }
0760:
0761:                commitManager.markPostModifyCommitInProgress(objectChangeSet);
0762:                commitManager.markPostModifyCommitInProgress(writeQuery
0763:                        .getObject());
0764:                // Verify if deep shallow modify is turned on.
0765:                if (writeQuery.shouldCascadeParts()) {
0766:                    queryManager.postInsert(writeQuery);
0767:                }
0768:
0769:                // PERF: Avoid events if no listeners.
0770:                if (getDescriptor().getEventManager().hasAnyEventListeners()) {
0771:                    getDescriptor().getEventManager().executeEvent(
0772:                            new DescriptorEvent(
0773:                                    DescriptorEventManager.PostInsertEvent,
0774:                                    writeQuery));
0775:                }
0776:            }
0777:
0778:            /**
0779:             * Return true if this is a call query mechanism
0780:             */
0781:            public boolean isCallQueryMechanism() {
0782:                return false;
0783:            }
0784:
0785:            /**
0786:             * Return true if this is an expression query mechanism
0787:             */
0788:            public boolean isExpressionQueryMechanism() {
0789:                return false;
0790:            }
0791:
0792:            /**
0793:             * Return true if this is a query by example mechanism
0794:             */
0795:            public boolean isQueryByExampleMechanism() {
0796:                return false;
0797:            }
0798:
0799:            /**
0800:             * Return true if this is a statement query mechanism
0801:             */
0802:            public boolean isStatementQueryMechanism() {
0803:                return false;
0804:            }
0805:
0806:            /**
0807:             * Delete the object using the user defined query.
0808:             * This ensures that the query is cloned and prepared correctly.
0809:             */
0810:            protected void performUserDefinedDelete() {
0811:                performUserDefinedWrite(getDescriptor().getQueryManager()
0812:                        .getDeleteQuery());
0813:            }
0814:
0815:            /**
0816:             * Insert the object using the user defined query.
0817:             * This ensures that the query is cloned and prepared correctly.
0818:             */
0819:            protected void performUserDefinedInsert() {
0820:                performUserDefinedWrite(getDescriptor().getQueryManager()
0821:                        .getInsertQuery());
0822:            }
0823:
0824:            /**
0825:             * Update the object using the user defined query.
0826:             * This ensures that the query is cloned and prepared correctly.
0827:             */
0828:            protected void performUserDefinedUpdate() {
0829:                performUserDefinedWrite(getDescriptor().getQueryManager()
0830:                        .getUpdateQuery());
0831:            }
0832:
0833:            /**
0834:             * Write the object using the specified user-defined query.
0835:             * This ensures that the query is cloned and prepared correctly.
0836:             */
0837:            protected void performUserDefinedWrite(
0838:                    WriteObjectQuery userDefinedWriteQuery) {
0839:                userDefinedWriteQuery.checkPrepare(getSession(),
0840:                        getTranslationRow());
0841:
0842:                Object object = getWriteObjectQuery().getObject();
0843:                WriteObjectQuery writeQuery = (WriteObjectQuery) userDefinedWriteQuery
0844:                        .clone();
0845:                writeQuery.setObject(object);
0846:                writeQuery.setObjectChangeSet(getWriteObjectQuery()
0847:                        .getObjectChangeSet());
0848:                writeQuery.setCascadePolicy(getQuery().getCascadePolicy());
0849:                writeQuery.setShouldMaintainCache(getQuery()
0850:                        .shouldMaintainCache());
0851:                writeQuery.setTranslationRow(getTranslationRow());
0852:                writeQuery.setModifyRow(getModifyRow());
0853:                writeQuery.setPrimaryKey(getWriteObjectQuery().getPrimaryKey());
0854:                writeQuery.setSession(getSession());
0855:                writeQuery.prepareForExecution();
0856:
0857:                // HACK: If there is a changeset, the change set method must be used,
0858:                // however it is currently broken for inserts, so until this is fixed,
0859:                // only using correct commit for updates.
0860:                if (getWriteObjectQuery().isUpdateObjectQuery()
0861:                        && (getWriteObjectQuery().getObjectChangeSet() != null)) {
0862:                    writeQuery.executeCommitWithChangeSet();
0863:                } else {
0864:                    writeQuery.executeCommit();
0865:                }
0866:            }
0867:
0868:            /**
0869:             * This is different from 'prepareForExecution()'
0870:             * in that this is called on the original query,
0871:             * and the other is called on the clone of the query.
0872:             * This query is copied for concurrency so this prepare can only setup things that
0873:             * will apply to any future execution of this query.
0874:             */
0875:            public void prepare() throws QueryException {
0876:                // the default is to do nothing
0877:            }
0878:
0879:            /**
0880:             * Pre-pare for a cursored execute.
0881:             * This is sent to the original query before cloning.
0882:             */
0883:            public abstract void prepareCursorSelectAllRows()
0884:                    throws QueryException;
0885:
0886:            /**
0887:             * Prepare for a delete all.
0888:             * This is sent to the original query before cloning.
0889:             */
0890:            public abstract void prepareDeleteAll() throws QueryException;
0891:
0892:            /**
0893:             * Prepare for a delete.
0894:             * This is sent to the original query before cloning.
0895:             */
0896:            public abstract void prepareDeleteObject() throws QueryException;
0897:
0898:            /**
0899:             * Pre-pare for a select execute.
0900:             * This is sent to the original query before cloning.
0901:             */
0902:            public abstract void prepareDoesExist(DatabaseField field)
0903:                    throws QueryException;
0904:
0905:            /**
0906:             * Prepare for a raw (non-object), non-selecting call.
0907:             * This is sent to the original query before cloning.
0908:             */
0909:            public abstract void prepareExecuteNoSelect() throws QueryException;
0910:
0911:            /**
0912:             * Prepare for a raw (non-object) select call.
0913:             * This is sent to the original query before cloning.
0914:             */
0915:            public abstract void prepareExecuteSelect() throws QueryException;
0916:
0917:            /**
0918:             * All the query mechanism related things are initialized here.
0919:             * This method is called on the *clone* of the query with
0920:             * every execution.
0921:             */
0922:            public void prepareForExecution() throws QueryException {
0923:                // the default is to do nothing
0924:            }
0925:
0926:            /**
0927:             * Prepare for an insert.
0928:             * This is sent to the original query before cloning.
0929:             */
0930:            public abstract void prepareInsertObject() throws QueryException;
0931:
0932:            /**
0933:             * Pre-pare for a select execute.
0934:             * This is sent to the original query before cloning.
0935:             */
0936:            public abstract void prepareReportQuerySelectAllRows()
0937:                    throws QueryException;
0938:
0939:            /**
0940:             * Pre-pare a report query for a sub-select.
0941:             */
0942:            public abstract void prepareReportQuerySubSelect()
0943:                    throws QueryException;
0944:
0945:            /**
0946:             * Prepare for a select returning (possibly) multiple rows.
0947:             * This is sent to the original query before cloning.
0948:             */
0949:            public abstract void prepareSelectAllRows() throws QueryException;
0950:
0951:            /**
0952:             * Prepare for a select returning a single row.
0953:             * This is sent to the original query before cloning.
0954:             */
0955:            public abstract void prepareSelectOneRow() throws QueryException;
0956:
0957:            /**
0958:             * Prepare for an update.
0959:             * This is sent to the original query before cloning.
0960:             */
0961:            public abstract void prepareUpdateObject() throws QueryException;
0962:
0963:            /**
0964:             * Prepare for an update all.
0965:             * This is sent to the original query before cloning.
0966:             */
0967:            public abstract void prepareUpdateAll() throws QueryException;
0968:
0969:            /**
0970:             * Store the query object in the identity map.
0971:             */
0972:            protected void registerObjectInIdentityMap() {
0973:                WriteObjectQuery writeQuery = getWriteObjectQuery();
0974:                Object object = writeQuery.getObject();
0975:
0976:                if (writeQuery.shouldMaintainCache()) {
0977:                    if (getDescriptor().usesOptimisticLocking()) {
0978:                        Object optimisticLockValue = getDescriptor()
0979:                                .getOptimisticLockingPolicy()
0980:                                .getValueToPutInCache(
0981:                                        writeQuery.getModifyRow(), getSession());
0982:                        getSession().getIdentityMapAccessorInstance()
0983:                                .putInIdentityMap(object,
0984:                                        writeQuery.getPrimaryKey(),
0985:                                        optimisticLockValue,
0986:                                        System.currentTimeMillis(),
0987:                                        getDescriptor());
0988:                    } else {
0989:                        getSession().getIdentityMapAccessorInstance()
0990:                                .putInIdentityMap(object,
0991:                                        writeQuery.getPrimaryKey(), null,
0992:                                        System.currentTimeMillis(),
0993:                                        getDescriptor());
0994:                    }
0995:                }
0996:            }
0997:
0998:            /**
0999:             * INTERNAL:
1000:             * Read all rows from the database.
1001:             */
1002:            public abstract Vector selectAllReportQueryRows()
1003:                    throws DatabaseException;
1004:
1005:            /**
1006:             * Read and return rows from the database.
1007:             */
1008:            public abstract Vector selectAllRows() throws DatabaseException;
1009:
1010:            /**
1011:             * Read and return a row from the database.
1012:             */
1013:            public abstract AbstractRecord selectOneRow()
1014:                    throws DatabaseException;
1015:
1016:            /**
1017:             * Read and return a row from the database for an existence check.
1018:             */
1019:            public abstract AbstractRecord selectRowForDoesExist(
1020:                    DatabaseField field) throws DatabaseException;
1021:
1022:            /**
1023:             * Set the query that uses this mechanism.
1024:             */
1025:            public void setQuery(DatabaseQuery query) {
1026:                this .query = query;
1027:            }
1028:
1029:            /**
1030:             * INTERNAL:
1031:             * Shallow delete the specified object.
1032:             */
1033:            public void shallowDeleteObjectForWrite(Object object,
1034:                    WriteObjectQuery writeQuery, CommitManager commitManager)
1035:                    throws DatabaseException, OptimisticLockException {
1036:                // a shallow delete must be performed
1037:                writeQuery.dontCascadeParts();
1038:                deleteObjectForWrite();
1039:                // mark this object as shallow committed so that the delete will be executed
1040:                commitManager.markShallowCommit(object);
1041:            }
1042:
1043:            /**
1044:             * INTERNAL:
1045:             * Shallow insert the specified object.
1046:             */
1047:            public void shallowInsertObjectForWrite(Object object,
1048:                    WriteObjectQuery writeQuery, CommitManager commitManager)
1049:                    throws DatabaseException, OptimisticLockException {
1050:                // a shallow insert must be performed
1051:                writeQuery.dontCascadeParts();
1052:                insertObjectForWrite();
1053:                // mark this object as shallow committed so that the insert will do an update
1054:                commitManager.markShallowCommit(object);
1055:            }
1056:
1057:            /**
1058:             * Update the foreign key fields when resolving a bi-directonal reference in a UOW.
1059:             * This must always be dynamic as it is called within an insert query and is really part of the insert
1060:             * and does not fire update events or worry about locking.
1061:             */
1062:            protected void updateForeignKeyFieldAfterInsert() {
1063:                WriteObjectQuery writeQuery = getWriteObjectQuery();
1064:                Object object = writeQuery.getObject();
1065:
1066:                writeQuery.setPrimaryKey(getDescriptor().getObjectBuilder()
1067:                        .extractPrimaryKeyFromObject(object, getSession()));
1068:                // reset the translation row because the insert has occurred and the id has
1069:                // been assigned to the object, but not the row
1070:                writeQuery.setTranslationRow(getDescriptor().getObjectBuilder()
1071:                        .buildRowForTranslation(object, getSession()));
1072:
1073:                writeQuery.setModifyRow(getDescriptor().getObjectBuilder()
1074:                        .buildRowForUpdate(writeQuery));
1075:
1076:                updateForeignKeyFieldShallow(writeQuery);
1077:            }
1078:
1079:            /**
1080:             * Null out the foreign key fields when resolving a bi-directonal reference in a UOW.
1081:             * This must always be dynamic as it is called within a delete query and is really part of the delete
1082:             * and does not fire update events or worry about locking.
1083:             */
1084:            protected void updateForeignKeyFieldBeforeDelete() {
1085:                WriteObjectQuery writeQuery = getWriteObjectQuery();
1086:                Object object = writeQuery.getObject();
1087:
1088:                writeQuery.setPrimaryKey(getDescriptor().getObjectBuilder()
1089:                        .extractPrimaryKeyFromObject(object, getSession()));
1090:                // set the translation row
1091:                writeQuery.setTranslationRow(getDescriptor().getObjectBuilder()
1092:                        .buildRowForTranslation(object, getSession()));
1093:                // build a query to null out the foreign keys
1094:                writeQuery.setModifyRow(getDescriptor().getObjectBuilder()
1095:                        .buildRowForShallowDelete(object, getSession()));
1096:
1097:                updateForeignKeyFieldShallow(writeQuery);
1098:            }
1099:
1100:            /**
1101:             * Issue update SQL statement
1102:             */
1103:            public abstract Integer updateAll() throws DatabaseException;
1104:
1105:            /**
1106:             * Update an object.
1107:             * Return the row count.
1108:             */
1109:            public abstract Integer updateObject() throws DatabaseException;
1110:
1111:            /**
1112:             * Update the foreign key fields when resolving a bi-directonal reference in a UOW.
1113:             * This must always be dynamic as it is called within an insert query and is really part of the insert
1114:             * and does not fire update events or worry about locking.
1115:             */
1116:            protected abstract void updateForeignKeyFieldShallow(
1117:                    WriteObjectQuery writeQuery);
1118:
1119:            protected void updateObjectAndRowWithReturnRow(
1120:                    Collection returnFields, boolean isFirstCallForInsert) {
1121:                WriteObjectQuery writeQuery = getWriteObjectQuery();
1122:                AbstractRecord outputRow = (AbstractRecord) writeQuery
1123:                        .getProperties().get("output");
1124:                if ((outputRow == null) || outputRow.isEmpty()) {
1125:                    return;
1126:                }
1127:                AbstractRecord row = new DatabaseRecord();
1128:                for (Iterator iterator = returnFields.iterator(); iterator
1129:                        .hasNext();) {
1130:                    DatabaseField field = (DatabaseField) iterator.next();
1131:                    if (outputRow.containsKey(field)) {
1132:                        row.put(field, outputRow.get(field));
1133:                    }
1134:                }
1135:                if (row.isEmpty()) {
1136:                    return;
1137:                }
1138:
1139:                Object object = writeQuery.getObject();
1140:
1141:                getDescriptor().getObjectBuilder().assignReturnRow(object,
1142:                        getSession(), row);
1143:
1144:                Vector primaryKeys = null;
1145:                if (isFirstCallForInsert) {
1146:                    AbstractRecord pkToModify = new DatabaseRecord();
1147:                    List primaryKeyFields = getDescriptor()
1148:                            .getPrimaryKeyFields();
1149:                    for (int i = 0; i < primaryKeyFields.size(); i++) {
1150:                        DatabaseField field = (DatabaseField) primaryKeyFields
1151:                                .get(i);
1152:                        if (row.containsKey(field)) {
1153:                            pkToModify.put(field, row.get(field));
1154:                        }
1155:                    }
1156:                    if (!pkToModify.isEmpty()) {
1157:                        primaryKeys = getDescriptor().getObjectBuilder()
1158:                                .extractPrimaryKeyFromObject(object,
1159:                                        getSession());
1160:                        writeQuery.setPrimaryKey(primaryKeys);
1161:                        // Now I need to update the row
1162:                        getModifyRow().putAll(pkToModify);
1163:                        getDescriptor()
1164:                                .getObjectBuilder()
1165:                                .addPrimaryKeyForNonDefaultTable(getModifyRow());
1166:                    }
1167:                }
1168:
1169:                // update the changeSet if there is one
1170:                if (getSession().isUnitOfWork()) {
1171:                    ObjectChangeSet objectChangeSet = writeQuery
1172:                            .getObjectChangeSet();
1173:                    if ((objectChangeSet == null)
1174:                            && (((UnitOfWorkImpl) getSession())
1175:                                    .getUnitOfWorkChangeSet() != null)) {
1176:                        objectChangeSet = (ObjectChangeSet) ((UnitOfWorkImpl) getSession())
1177:                                .getUnitOfWorkChangeSet()
1178:                                .getObjectChangeSetForClone(object);
1179:                    }
1180:                    if (objectChangeSet != null) {
1181:                        updateChangeSet(getDescriptor(), objectChangeSet, row,
1182:                                object);
1183:                        if (primaryKeys != null) {
1184:                            objectChangeSet.setCacheKey(new CacheKey(
1185:                                    primaryKeys));
1186:                        }
1187:                    }
1188:                }
1189:            }
1190:
1191:            /**
1192:             * Update the change set with all of the field values in the row.
1193:             * This handle writable and read-only mappings, direct and nested aggregates.
1194:             * It is used from ReturningPolicy and VersionLockingPolicy.
1195:             */
1196:            public void updateChangeSet(ClassDescriptor desc,
1197:                    ObjectChangeSet objectChangeSet, AbstractRecord row,
1198:                    Object object) {
1199:                HashSet handledMappings = new HashSet(row.size());
1200:                for (int i = 0; i < row.size(); i++) {
1201:                    DatabaseField field = (DatabaseField) row.getFields()
1202:                            .elementAt(i);
1203:                    Object value = row.getValues().elementAt(i);
1204:                    updateChangeSet(desc, objectChangeSet, field, object,
1205:                            handledMappings);
1206:                }
1207:            }
1208:
1209:            protected void updateChangeSet(ClassDescriptor desc,
1210:                    ObjectChangeSet objectChangeSet, DatabaseField field,
1211:                    Object object) {
1212:                updateChangeSet(desc, objectChangeSet, field, object, null);
1213:            }
1214:
1215:            protected void updateChangeSet(ClassDescriptor desc,
1216:                    ObjectChangeSet objectChangeSet, DatabaseField field,
1217:                    Object object, Collection handledMappings) {
1218:                DatabaseMapping mapping;
1219:                Vector mappingVector = desc.getObjectBuilder()
1220:                        .getReadOnlyMappingsForField(field);
1221:                if (mappingVector != null) {
1222:                    for (int j = 0; j < mappingVector.size(); j++) {
1223:                        mapping = (DatabaseMapping) mappingVector.elementAt(j);
1224:                        updateChangeSet(mapping, objectChangeSet, field,
1225:                                object, handledMappings);
1226:                    }
1227:                }
1228:                mapping = desc.getObjectBuilder().getMappingForField(field);
1229:                if (mapping != null) {
1230:                    updateChangeSet(mapping, objectChangeSet, field, object,
1231:                            handledMappings);
1232:                }
1233:            }
1234:
1235:            protected void updateChangeSet(DatabaseMapping mapping,
1236:                    ObjectChangeSet objectChangeSet, DatabaseField field,
1237:                    Object object, Collection handledMappings) {
1238:                if ((handledMappings != null)
1239:                        && handledMappings.contains(mapping)) {
1240:                    return;
1241:                }
1242:                if (mapping.isAggregateObjectMapping()) {
1243:                    Object aggregate = mapping
1244:                            .getAttributeValueFromObject(object);
1245:                    AggregateChangeRecord record = (AggregateChangeRecord) objectChangeSet
1246:                            .getChangesForAttributeNamed(mapping
1247:                                    .getAttributeName());
1248:                    if (aggregate != null) {
1249:                        if (record == null) {
1250:                            record = new AggregateChangeRecord(objectChangeSet);
1251:                            record.setAttribute(mapping.getAttributeName());
1252:                            record.setMapping(mapping);
1253:                            objectChangeSet.addChange(record);
1254:                        }
1255:                        ObjectChangeSet aggregateChangeSet = (oracle.toplink.essentials.internal.sessions.ObjectChangeSet) record
1256:                                .getChangedObject();
1257:                        ClassDescriptor aggregateDescriptor = ((AggregateObjectMapping) mapping)
1258:                                .getReferenceDescriptor();
1259:                        if (aggregateChangeSet == null) {
1260:                            aggregateChangeSet = aggregateDescriptor
1261:                                    .getObjectBuilder()
1262:                                    .createObjectChangeSet(
1263:                                            aggregate,
1264:                                            (oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet) ((UnitOfWorkImpl) getSession())
1265:                                                    .getUnitOfWorkChangeSet(),
1266:                                            getSession());
1267:                            record.setChangedObject(aggregateChangeSet);
1268:                        }
1269:                        updateChangeSet(aggregateDescriptor,
1270:                                aggregateChangeSet, field, aggregate,
1271:                                handledMappings);
1272:                    } else {
1273:                        if (record != null) {
1274:                            record.setChangedObject(null);
1275:                        }
1276:                    }
1277:                } else if (mapping.isDirectToFieldMapping()) {
1278:                    Object attributeValue = mapping
1279:                            .getAttributeValueFromObject(object);
1280:                    objectChangeSet.updateChangeRecordForAttribute(mapping,
1281:                            attributeValue);
1282:                } else {
1283:                    getSession().log(SessionLog.FINEST, SessionLog.QUERY,
1284:                            "field_for_unsupported_mapping_returned", field,
1285:                            getDescriptor());
1286:                }
1287:            }
1288:
1289:            /**
1290:             * Update the object's primary key by fetching a new sequence number from the accessor.
1291:             */
1292:            protected void updateObjectAndRowWithSequenceNumber()
1293:                    throws DatabaseException {
1294:                WriteObjectQuery writeQuery = getWriteObjectQuery();
1295:                Object object = writeQuery.getObject();
1296:
1297:                Object sequenceValue = getDescriptor().getObjectBuilder()
1298:                        .assignSequenceNumber(object, getSession());
1299:                if (sequenceValue == null) {
1300:                    return;
1301:                }
1302:                Vector primaryKeys = getDescriptor().getObjectBuilder()
1303:                        .extractPrimaryKeyFromObject(object, getSession());
1304:                writeQuery.setPrimaryKey(primaryKeys);
1305:                DatabaseField sequenceNumberField = getDescriptor()
1306:                        .getSequenceNumberField();
1307:
1308:                // Now I need to update the row
1309:                getModifyRow().put(sequenceNumberField, sequenceValue);
1310:                getDescriptor().getObjectBuilder()
1311:                        .addPrimaryKeyForNonDefaultTable(getModifyRow());
1312:                // update the changeSet if there is one
1313:                if (getSession().isUnitOfWork()) {
1314:                    ObjectChangeSet objectChangeSet = writeQuery
1315:                            .getObjectChangeSet();
1316:                    if ((objectChangeSet == null)
1317:                            && (((UnitOfWorkImpl) getSession())
1318:                                    .getUnitOfWorkChangeSet() != null)) {
1319:                        objectChangeSet = (ObjectChangeSet) ((UnitOfWorkImpl) getSession())
1320:                                .getUnitOfWorkChangeSet()
1321:                                .getObjectChangeSetForClone(object);
1322:                    }
1323:                    if (objectChangeSet != null) {
1324:                        updateChangeSet(getDescriptor(), objectChangeSet,
1325:                                sequenceNumberField, object);
1326:                        objectChangeSet.setCacheKey(new CacheKey(primaryKeys));
1327:                    }
1328:                }
1329:            }
1330:
1331:            /**
1332:             * Update the object
1333:             */
1334:            public void updateObjectForWrite() {
1335:                WriteObjectQuery writeQuery = getWriteObjectQuery();
1336:                Object object = writeQuery.getObject();
1337:                DescriptorQueryManager queryManager = getDescriptor()
1338:                        .getQueryManager();
1339:
1340:                // check for user-defined query
1341:                if ((!writeQuery.isUserDefined())// this is not a user-defined query
1342:                        && queryManager.hasUpdateQuery()// there is a user-defined query
1343:                        && isExpressionQueryMechanism()) {// this is not a hand-coded call (custom SQL etc.)
1344:                    performUserDefinedUpdate();
1345:                    return;
1346:                }
1347:
1348:                // This must be done after the custom query check, otherwise it will be done twice.
1349:                getSession().getCommitManager().markPreModifyCommitInProgress(
1350:                        object);
1351:
1352:                if (writeQuery.getObjectChangeSet() == null) {
1353:                    // PERF: Avoid events if no listeners.
1354:                    if (getDescriptor().getEventManager()
1355:                            .hasAnyEventListeners()) {
1356:                        // only throw the events if there is no changeset otherwise the event will be thrown twice
1357:                        // once by the calculate changes code and here
1358:                        getDescriptor().getEventManager().executeEvent(
1359:                                new DescriptorEvent(
1360:                                        DescriptorEventManager.PreUpdateEvent,
1361:                                        writeQuery));
1362:                    }
1363:                }
1364:
1365:                // Verify if deep shallow modify is turned on
1366:                if (writeQuery.shouldCascadeParts()) {
1367:                    queryManager.preUpdate(writeQuery);
1368:                }
1369:
1370:                // The row must not be built until after preUpdate in case the object reference has changed.
1371:                // For a user defined update in the uow to row must be built twice to check if any update is required.
1372:                if ((writeQuery.isUserDefined() || writeQuery.isCallQuery())
1373:                        && (!getSession().isUnitOfWork())) {
1374:                    writeQuery.setModifyRow(getDescriptor().getObjectBuilder()
1375:                            .buildRow(object, getSession()));
1376:                } else {
1377:                    writeQuery.setModifyRow(getDescriptor().getObjectBuilder()
1378:                            .buildRowForUpdate(writeQuery));
1379:                }
1380:
1381:                if (!getModifyRow().isEmpty()) {
1382:                    // If user defined the entire row is required. Must not be built until change is known.
1383:                    if ((writeQuery.isUserDefined() || writeQuery.isCallQuery())
1384:                            && getSession().isUnitOfWork()) {
1385:                        writeQuery.setModifyRow(getDescriptor()
1386:                                .getObjectBuilder().buildRow(object,
1387:                                        getSession()));
1388:                    }
1389:
1390:                    // Update the write lock field if required
1391:                    if (getDescriptor().usesOptimisticLocking()) {
1392:                        OptimisticLockingPolicy policy = getDescriptor()
1393:                                .getOptimisticLockingPolicy();
1394:                        policy.addLockValuesToTranslationRow(writeQuery);
1395:
1396:                        // update the row with newer lock value		
1397:                        policy.updateRowAndObjectForUpdate(writeQuery, object);
1398:                    }
1399:
1400:                    // PERF: Avoid events if no listeners.
1401:                    if (getDescriptor().getEventManager()
1402:                            .hasAnyEventListeners()) {
1403:                        DescriptorEvent event = new DescriptorEvent(
1404:                                DescriptorEventManager.AboutToUpdateEvent,
1405:                                writeQuery);
1406:                        event.setRecord(getModifyRow());
1407:                        getDescriptor().getEventManager().executeEvent(event);
1408:                    }
1409:
1410:                    int rowCount = updateObject().intValue();
1411:
1412:                    if (rowCount < 1) {
1413:                        getSession().getEventManager().noRowsModified(
1414:                                writeQuery, object);
1415:                    }
1416:                    if (getDescriptor().usesOptimisticLocking()) {
1417:                        getDescriptor().getOptimisticLockingPolicy()
1418:                                .validateUpdate(rowCount, object, writeQuery);
1419:                    }
1420:                }
1421:
1422:                getSession().getCommitManager().markPostModifyCommitInProgress(
1423:                        object);
1424:
1425:                // Verify if deep shallow modify is turned on
1426:                if (writeQuery.shouldCascadeParts()) {
1427:                    queryManager.postUpdate(writeQuery);
1428:                }
1429:
1430:                // PERF: Avoid events if no listeners.
1431:                if (getDescriptor().getEventManager().hasAnyEventListeners()) {
1432:                    getDescriptor().getEventManager().executeEvent(
1433:                            new DescriptorEvent(
1434:                                    DescriptorEventManager.PostUpdateEvent,
1435:                                    writeQuery));
1436:                }
1437:            }
1438:
1439:            /**
1440:             * Update the object
1441:             */
1442:            public void updateObjectForWriteWithChangeSet() {
1443:                WriteObjectQuery writeQuery = getWriteObjectQuery();
1444:                Object object = writeQuery.getObject();
1445:                DescriptorQueryManager queryManager = getDescriptor()
1446:                        .getQueryManager();
1447:
1448:                // check for user-defined query
1449:                if ((!writeQuery.isUserDefined())// this is not a user-defined query
1450:                        && queryManager.hasUpdateQuery()// there is a user-defined query
1451:                        && isExpressionQueryMechanism()) {// this is not a hand-coded call (custom SQL etc.)
1452:                    // THis must be done here because the userdefined updatedoes not use a changeset so it will noe be set otherwise
1453:                    getSession().getCommitManager()
1454:                            .markPreModifyCommitInProgress(
1455:                                    writeQuery.getObjectChangeSet());
1456:                    performUserDefinedUpdate();
1457:                    return;
1458:                }
1459:
1460:                // This must be done after the custom query check, otherwise it will be done twice.
1461:                getSession().getCommitManager().markPreModifyCommitInProgress(
1462:                        object);
1463:                // This must be done after the custom query check, otherwise it will be done twice.
1464:                getSession().getCommitManager().markPreModifyCommitInProgress(
1465:                        writeQuery.getObjectChangeSet());
1466:
1467:                if (writeQuery.getObjectChangeSet().hasChanges()) {
1468:                    // PERF: Avoid events if no listeners.
1469:                    if (getDescriptor().getEventManager()
1470:                            .hasAnyEventListeners()) {
1471:                        DescriptorEvent event = new DescriptorEvent(
1472:                                DescriptorEventManager.PreUpdateWithChangesEvent,
1473:                                writeQuery);
1474:                        getDescriptor().getEventManager().executeEvent(event);
1475:
1476:                        // PreUpdateWithChangesEvent listeners may have altered the object - should recalculate the change set.
1477:                        UnitOfWorkChangeSet uowChangeSet = (oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet) ((UnitOfWorkImpl) writeQuery
1478:                                .getSession()).getUnitOfWorkChangeSet();
1479:                        // writeQuery.getObjectChangeSet() is mapped to object in uowChangeSet.
1480:                        // It is first cleared then re-populated by calculateChanges method.
1481:                        writeQuery.getObjectChangeSet().clear();
1482:                        if (writeQuery.getDescriptor().getObjectChangePolicy()
1483:                                .calculateChanges(
1484:                                        object,
1485:                                        ((UnitOfWorkImpl) event.getSession())
1486:                                                .getBackupClone(object),
1487:                                        uowChangeSet, writeQuery.getSession(),
1488:                                        writeQuery.getDescriptor(), false) == null) {
1489:                            // calculateChanges returns null in case the changeSet doesn't have changes.
1490:                            // It should be removed from the list of ObjectChangeSets that have changes in uowChangeSet.
1491:                            uowChangeSet.getAllChangeSets().remove(
1492:                                    writeQuery.getObjectChangeSet());
1493:                        }
1494:                    }
1495:                }
1496:
1497:                // Verify if deep shallow modify is turned on
1498:                if (writeQuery.shouldCascadeParts()) {
1499:                    queryManager.preUpdate(writeQuery);
1500:                }
1501:
1502:                // The row must not be built until after preUpdate in case the object reference has changed.
1503:                // For a user defined update in the uow to row must be built twice to check if any update is required.
1504:                writeQuery.setModifyRow(getDescriptor().getObjectBuilder()
1505:                        .buildRowForUpdateWithChangeSet(writeQuery));
1506:
1507:                Boolean shouldModifyVersionField = writeQuery
1508:                        .getObjectChangeSet().shouldModifyVersionField();
1509:
1510:                if (!getModifyRow().isEmpty()
1511:                        || (shouldModifyVersionField != null)
1512:                        || writeQuery.getObjectChangeSet()
1513:                                .hasCmpPolicyForcedUpdate()) {
1514:                    // If user defined the entire row is required. Must not be built until change is known.
1515:                    if (writeQuery.isUserDefined() || writeQuery.isCallQuery()) {
1516:                        writeQuery.setModifyRow(getDescriptor()
1517:                                .getObjectBuilder().buildRow(object,
1518:                                        getSession()));
1519:                    }
1520:
1521:                    // Update the write lock field if required
1522:                    if (getDescriptor().usesOptimisticLocking()) {
1523:                        OptimisticLockingPolicy policy = getDescriptor()
1524:                                .getOptimisticLockingPolicy();
1525:                        policy.addLockValuesToTranslationRow(writeQuery);
1526:
1527:                        if (!getModifyRow().isEmpty()
1528:                                || (shouldModifyVersionField.booleanValue() && policy instanceof  VersionLockingPolicy)) {
1529:                            // update the row with newer lock value		
1530:                            policy.updateRowAndObjectForUpdate(writeQuery,
1531:                                    object);
1532:                        } else if (!shouldModifyVersionField.booleanValue()
1533:                                && policy instanceof  VersionLockingPolicy) {
1534:                            ((VersionLockingPolicy) policy)
1535:                                    .writeLockValueIntoRow(writeQuery, object);
1536:                        }
1537:                    }
1538:
1539:                    // PERF: Avoid events if no listeners.
1540:                    if (getDescriptor().getEventManager()
1541:                            .hasAnyEventListeners()) {
1542:                        DescriptorEvent event = new DescriptorEvent(
1543:                                DescriptorEventManager.AboutToUpdateEvent,
1544:                                writeQuery);
1545:                        event.setRecord(getModifyRow());
1546:                        getDescriptor().getEventManager().executeEvent(event);
1547:                    }
1548:
1549:                    int rowCount = updateObject().intValue();
1550:
1551:                    if (rowCount < 1) {
1552:                        getSession().getEventManager().noRowsModified(
1553:                                writeQuery, object);
1554:                    }
1555:                    if (getDescriptor().usesOptimisticLocking()) {
1556:                        getDescriptor().getOptimisticLockingPolicy()
1557:                                .validateUpdate(rowCount, object, writeQuery);
1558:                    }
1559:                }
1560:
1561:                getSession().getCommitManager().markPostModifyCommitInProgress(
1562:                        object);
1563:                getSession().getCommitManager().markPostModifyCommitInProgress(
1564:                        writeQuery.getObjectChangeSet());
1565:
1566:                // Verify if deep shallow modify is turned on
1567:                if (writeQuery.shouldCascadeParts()) {
1568:                    queryManager.postUpdate(writeQuery);
1569:                }
1570:
1571:                // PERF: Avoid events if no listeners.
1572:                if (getDescriptor().getEventManager().hasAnyEventListeners()) {
1573:                    getDescriptor().getEventManager().executeEvent(
1574:                            new DescriptorEvent(
1575:                                    DescriptorEventManager.PostUpdateEvent,
1576:                                    writeQuery));
1577:                }
1578:            }
1579:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.