1 21 package oracle.toplink.essentials.internal.sessions; 23 24 import java.util.*; 25 import java.io.*; 26 import javax.persistence.EntityExistsException; 27 import oracle.toplink.essentials.internal.helper.*; 28 import oracle.toplink.essentials.internal.descriptors.*; 29 import oracle.toplink.essentials.internal.localization.ExceptionLocalization; 30 import oracle.toplink.essentials.platform.server.ServerPlatform; 31 import oracle.toplink.essentials.queryframework.*; 32 import oracle.toplink.essentials.internal.identitymaps.*; 33 import oracle.toplink.essentials.internal.databaseaccess.*; 34 import oracle.toplink.essentials.expressions.*; 35 import oracle.toplink.essentials.exceptions.*; 36 import oracle.toplink.essentials.internal.sequencing.Sequencing; 37 import oracle.toplink.essentials.logging.SessionLog; 38 import oracle.toplink.essentials.internal.localization.LoggingLocalization; 39 import oracle.toplink.essentials.sessions.SessionProfiler; 40 import oracle.toplink.essentials.sessions.UnitOfWork; 41 import oracle.toplink.essentials.internal.sessions.AbstractSession; 42 import oracle.toplink.essentials.descriptors.DescriptorEventManager; 43 import oracle.toplink.essentials.internal.sessions.AbstractRecord; 44 import oracle.toplink.essentials.internal.helper.IdentityHashtable; 45 46 import oracle.toplink.essentials.descriptors.ClassDescriptor; 47 import oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager; 48 49 76 public class UnitOfWorkImpl extends AbstractSession implements oracle.toplink.essentials.sessions.UnitOfWork { 77 78 79 80 protected transient IdentityHashtable cloneToOriginals; 81 protected transient AbstractSession parent; 82 83 84 protected IdentityHashtable cloneMapping; 85 protected IdentityHashtable newObjectsCloneToOriginal; 86 protected IdentityHashtable newObjectsOriginalToClone; 87 protected IdentityHashtable deletedObjects; 88 89 90 protected IdentityHashtable allClones; 91 protected IdentityHashtable objectsDeletedDuringCommit; 92 protected IdentityHashtable removedObjects; 93 protected IdentityHashtable unregisteredNewObjects; 94 protected IdentityHashtable unregisteredExistingObjects; 95 96 protected IdentityHashtable newAggregates; 97 98 99 protected UnitOfWorkChangeSet unitOfWorkChangeSet; 100 101 102 protected IdentityHashtable pessimisticLockedObjects; 103 104 105 protected MergeManager lastUsedMergeManager; 106 107 108 protected Hashtable readOnlyClasses; 109 110 111 protected boolean wasTransactionBegunPrematurely; 112 113 114 protected boolean shouldNewObjectsBeCached; 115 116 117 protected boolean shouldPerformDeletesFirst; 118 119 120 protected int shouldThrowConformExceptions; 121 122 123 protected int validationLevel; 124 static public final int None = 0; 125 static public final int Partial = 1; 126 static public final int Full = 2; 127 128 132 protected boolean isSynchronized; 133 protected int lifecycle; 134 public static final int Birth = 0; 135 public static final int CommitPending = 1; 136 137 public static final int CommitTransactionPending = 2; 139 140 public static final int WriteChangesFailed = 3; 142 public static final int MergePending = 4; 143 public static final int Death = 5; 144 public static final int AfterExternalTransactionRolledBack = 6; 145 146 147 public static final int DO_NOT_THROW_CONFORM_EXCEPTIONS = 0; 148 public static final int THROW_ALL_CONFORM_EXCEPTIONS = 1; 149 150 public static final String LOCK_QUERIES_PROPERTY = "LockQueriesProperties"; 151 152 153 protected static boolean SmartMerge = false; 154 155 156 protected Hashtable optimisticReadLockObjects; 157 158 159 protected List modifyAllQueries; 160 161 162 protected List deferredModifyAllQueries; 164 165 170 protected int cloneDepth = 0; 171 172 176 protected Map objectsLockedForClone; 177 178 181 protected Object transaction; 182 183 184 185 186 187 188 191 protected boolean shouldCheckWriteLock; 192 193 197 protected boolean resumeOnTransactionCompletion; 198 199 203 protected boolean wasNonObjectLevelModifyQueryExecuted; 204 205 209 protected boolean shouldCascadeCloneToJoinedRelationship; 210 211 215 public UnitOfWorkImpl(AbstractSession parent) { 216 super(); 217 this.name = parent.getName(); 218 this.parent = parent; 219 this.cloneMapping = new IdentityHashtable(); 221 this.project = parent.getProject(); 225 this.profiler = parent.getProfiler(); 226 this.isInProfile = parent.isInProfile; 227 this.sessionLog = parent.getSessionLog(); 228 this.eventManager = parent.getEventManager().clone(this); 229 this.exceptionHandler = parent.getExceptionHandler(); 230 231 this.setReadOnlyClasses(parent.copyReadOnlyClasses()); 233 this.wasTransactionBegunPrematurely = false; 234 this.shouldNewObjectsBeCached = false; 236 this.validationLevel = Partial; 237 238 this.shouldPerformDeletesFirst = false; 239 240 this.shouldThrowConformExceptions = DO_NOT_THROW_CONFORM_EXCEPTIONS; 242 243 this.isSynchronized = false; 245 this.lifecycle = Birth; 246 this.shouldCheckWriteLock = parent.getDatasourceLogin().shouldSynchronizedReadOnWrite() || parent.getDatasourceLogin().shouldSynchronizeWrites(); 248 this.resumeOnTransactionCompletion = false; 249 250 getEventManager().postAcquireUnitOfWork(); 251 incrementProfile(SessionProfiler.UowCreated); 252 } 253 254 258 public UnitOfWork acquireUnitOfWork() { 259 throw ValidationException.notSupported("acquireUnitOfWork", getClass()); 260 } 261 262 266 public void addNewAggregate(Object originalObject) { 267 getNewAggregates().put(originalObject, originalObject); 268 } 269 270 274 public void addObjectDeletedDuringCommit(Object object, ClassDescriptor descriptor) { 275 getObjectsDeletedDuringCommit().put(object, keyFromObject(object, descriptor)); 277 ((UnitOfWorkChangeSet)getUnitOfWorkChangeSet()).addDeletedObject(object, this); 279 } 280 281 286 public void addReadOnlyClass(Class theClass) throws ValidationException { 287 if (!canChangeReadOnlySet()) { 288 throw ValidationException.cannotModifyReadOnlyClassesSetAfterUsingUnitOfWork(); 289 } 290 291 getReadOnlyClasses().put(theClass, theClass); 292 293 ClassDescriptor descriptor = getDescriptor(theClass); 294 295 if (descriptor.hasInheritance()) { 297 for (Enumeration childEnum = descriptor.getInheritancePolicy().getChildDescriptors().elements(); 298 childEnum.hasMoreElements();) { 299 ClassDescriptor childDescriptor = (ClassDescriptor)childEnum.nextElement(); 300 addReadOnlyClass(childDescriptor.getJavaClass()); 301 } 302 } 303 } 304 305 310 public void addReadOnlyClasses(Vector classes) { 311 for (Enumeration enumtr = classes.elements(); enumtr.hasMoreElements();) { 312 Class theClass = (Class )enumtr.nextElement(); 313 addReadOnlyClass(theClass); 314 } 315 } 316 317 321 public void addRemovedObject(Object orignal) { 322 getRemovedObjects().put(orignal, orignal); } 324 325 332 public void assignSequenceNumber(Object object) throws DatabaseException { 333 startOperationProfile(SessionProfiler.AssignSequence); 335 try { 336 ObjectBuilder builder = getDescriptor(object).getObjectBuilder(); 337 338 if (builder.getDescriptor().usesSequenceNumbers() && !getSequencing().shouldAcquireValueAfterInsert(object.getClass())) { 340 Object implementation = builder.unwrapObject(object, this); 341 builder.assignSequenceNumber(implementation, this); 342 } 343 } catch (RuntimeException exception) { 344 handleException(exception); 345 } 346 endOperationProfile(SessionProfiler.AssignSequence); 347 } 348 349 357 public void assignSequenceNumbers() throws DatabaseException { 358 discoverAllUnregisteredNewObjects(); 369 Sequencing sequencing = getSequencing(); 370 if (sequencing == null) { 371 return; 372 } 373 int whenShouldAcquireValueForAll = sequencing.whenShouldAcquireValueForAll(); 374 if (whenShouldAcquireValueForAll == Sequencing.AFTER_INSERT) { 375 return; 376 } 377 boolean shouldAcquireValueBeforeInsertForAll = whenShouldAcquireValueForAll == Sequencing.BEFORE_INSERT; 378 startOperationProfile(SessionProfiler.AssignSequence); 379 Enumeration unregisteredNewObjectsEnum = getUnregisteredNewObjects().keys(); 380 while (unregisteredNewObjectsEnum.hasMoreElements()) { 381 Object object = unregisteredNewObjectsEnum.nextElement(); 382 if (getDescriptor(object).usesSequenceNumbers() && ((!isObjectRegistered(object)) || isCloneNewObject(object)) && (shouldAcquireValueBeforeInsertForAll || !sequencing.shouldAcquireValueAfterInsert(object.getClass()))) { 383 getDescriptor(object).getObjectBuilder().assignSequenceNumber(object, this); 384 } 385 } 386 Enumeration registeredNewObjectsEnum = getNewObjectsCloneToOriginal().keys(); 387 while (registeredNewObjectsEnum.hasMoreElements()) { 388 Object object = registeredNewObjectsEnum.nextElement(); 389 if (getDescriptor(object).usesSequenceNumbers() && ((!isObjectRegistered(object)) || isCloneNewObject(object)) && (shouldAcquireValueBeforeInsertForAll || !sequencing.shouldAcquireValueAfterInsert(object.getClass()))) { 390 getDescriptor(object).getObjectBuilder().assignSequenceNumber(object, this); 391 } 392 } 393 394 endOperationProfile(SessionProfiler.AssignSequence); 395 } 396 397 408 public void beginEarlyTransaction() throws DatabaseException { 409 beginTransaction(); 410 setWasTransactionBegunPrematurely(true); 411 } 412 413 418 public void beginTransaction() throws DatabaseException { 419 getParent().beginTransaction(); 420 } 421 422 427 public Object buildOriginal(Object workingClone) { 428 ClassDescriptor descriptor = getDescriptor(workingClone); 429 ObjectBuilder builder = descriptor.getObjectBuilder(); 430 Object original = builder.instantiateClone(workingClone, this); 431 432 if (checkIfAlreadyRegistered(workingClone, descriptor) != null) { 438 getCloneToOriginals().put(workingClone, original); 439 return original; 440 } else { 441 Object backup = builder.instantiateClone(workingClone, this); 444 445 getCloneMapping().put(workingClone, backup); 447 448 getNewObjectsCloneToOriginal().put(workingClone, original); 450 getNewObjectsOriginalToClone().put(original, workingClone); 451 452 } 455 return original; 456 } 457 458 463 public UnitOfWorkChangeSet calculateChanges(IdentityHashtable allObjects, UnitOfWorkChangeSet changeSet) { 464 getEventManager().preCalculateUnitOfWorkChangeSet(); 465 466 Enumeration objects = allObjects.elements(); 467 while (objects.hasMoreElements()) { 468 Object object = objects.nextElement(); 469 470 ClassDescriptor descriptor = getDescriptor(object); 472 473 if (descriptor.getObjectChangePolicy().shouldCompareForChange(object, this, descriptor)) { 476 ObjectChangeSet changes = descriptor.getObjectChangePolicy().calculateChanges(object, getBackupClone(object), changeSet, this, descriptor, true); 477 if ((changes != null) && changes.isNew()) { 478 changeSet.addNewObjectChangeSet(changes, this); 481 } else { 482 changeSet.addObjectChangeSet(changes); 483 } 484 } 485 } 486 487 getEventManager().postCalculateUnitOfWorkChangeSet(changeSet); 488 return changeSet; 489 } 490 491 497 protected boolean canChangeReadOnlySet() { 498 return !hasCloneMapping() && !hasDeletedObjects(); 499 } 500 501 504 public boolean checkForUnregisteredExistingObject(Object object) { 505 ClassDescriptor descriptor = getDescriptor(object.getClass()); 506 Vector primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(object, this); 507 508 DoesExistQuery existQuery = descriptor.getQueryManager().getDoesExistQuery(); 509 510 existQuery = (DoesExistQuery)existQuery.clone(); 511 existQuery.setObject(object); 512 existQuery.setPrimaryKey(primaryKey); 513 existQuery.setDescriptor(descriptor); 514 existQuery.setCheckCacheFirst(true); 515 516 if (((Boolean )executeQuery(existQuery)).booleanValue()) { 517 return true; 518 } else { 519 return false; 520 } 521 } 522 523 528 public Object checkExistence(Object object) { 529 ClassDescriptor descriptor = getDescriptor(object.getClass()); 530 Vector primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(object, this); 531 if (primaryKey.contains(null)) { 533 return null; 534 } 535 DoesExistQuery existQuery = descriptor.getQueryManager().getDoesExistQuery(); 536 537 existQuery = (DoesExistQuery)existQuery.clone(); 538 existQuery.setObject(object); 539 existQuery.setPrimaryKey(primaryKey); 540 existQuery.setDescriptor(descriptor); 541 existQuery.setCheckCacheFirst(true); 542 543 if (((Boolean )executeQuery(existQuery)).booleanValue()) { 544 Object objectFromCache = getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, object.getClass(), descriptor, null); 546 547 if (objectFromCache != null) { 548 if (shouldPerformFullValidation()) { 550 if ((objectFromCache != object) && (getParent().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, object.getClass(), descriptor, null) != object)) { 551 throw ValidationException.wrongObjectRegistered(object, objectFromCache); 552 } 553 } 554 555 if (!this.isObjectDeleted(objectFromCache)) 557 return objectFromCache; 558 } 559 return cloneAndRegisterObject(object, new CacheKey(primaryKey), null); 562 } else { 563 return null; 564 } 565 } 566 567 571 protected Object checkIfAlreadyRegistered(Object object, ClassDescriptor descriptor) { 572 if (isClassReadOnly(object.getClass(), descriptor)) { 574 return null; 575 } 576 577 Object registeredObject = getCloneMapping().get(object); 579 if (registeredObject != null) { 580 return object; 581 } 582 583 if (hasNewObjects()) { 587 registeredObject = getNewObjectsOriginalToClone().get(object); 588 if (registeredObject != null) { 589 return registeredObject; 590 } 591 } 592 593 return null; 594 } 595 596 606 protected Object cloneAndRegisterNewObject(Object original) { 607 ClassDescriptor descriptor = getDescriptor(original); 608 ObjectBuilder builder = descriptor.getObjectBuilder(); 609 610 Object clone = builder.instantiateWorkingCopyClone(original, this); 612 613 getNewObjectsOriginalToClone().put(original, clone); 615 getCloneMapping().put(clone, clone); 617 618 builder.populateAttributesForClone(original, clone, this, null); 619 620 registerNewObjectClone(clone, original); 622 623 Object backupClone = descriptor.getObjectChangePolicy().buildBackupClone(clone, builder, this); 626 getCloneMapping().put(clone, backupClone); 628 return clone; 629 } 630 631 637 public Object cloneAndRegisterObject(Object original, CacheKey cacheKey, JoinedAttributeManager joinedAttributeManager) { 638 ClassDescriptor descriptor = getDescriptor(original); 639 640 ObjectBuilder builder = descriptor.getObjectBuilder(); 641 Object workingClone = builder.instantiateWorkingCopyClone(original, this); 642 643 boolean identityMapLocked = this.shouldCheckWriteLock && getParent().getIdentityMapAccessorInstance().acquireWriteLock(); 651 boolean rootOfCloneRecursion = false; 652 if ((!identityMapLocked) && (this.objectsLockedForClone == null)) { if (descriptor.shouldAcquireCascadedLocks()) { 655 this.objectsLockedForClone = getParent().getIdentityMapAccessorInstance().getWriteLockManager().acquireLocksForClone(original, descriptor, cacheKey.getKey(), getParent()); 656 } else { 657 cacheKey.acquireReadLock(); 658 } 659 rootOfCloneRecursion = true; 660 } 661 try { 662 getCloneMapping().put(workingClone, workingClone); 664 665 if (descriptor.hasFetchGroupManager()) { 667 descriptor.getFetchGroupManager().copyFetchGroupInto(original, workingClone); 668 } 669 670 getCloneToOriginals().put(workingClone, original); 672 populateAndRegisterObject(original, workingClone, cacheKey.getKey(), descriptor, cacheKey.getWriteLockValue(), cacheKey.getReadTime(), joinedAttributeManager); 674 675 } finally { 676 if (identityMapLocked) { 680 getParent().getIdentityMapAccessorInstance().releaseWriteLock(); 681 } else { 682 if (rootOfCloneRecursion) { 683 if (this.objectsLockedForClone == null) { 684 cacheKey.releaseReadLock(); 685 } else { 686 for (Iterator iterator = this.objectsLockedForClone.values().iterator(); 687 iterator.hasNext();) { 688 ((CacheKey)iterator.next()).releaseReadLock(); 689 } 690 this.objectsLockedForClone = null; 691 } 692 } 693 } 694 } 695 return workingClone; 696 } 697 698 702 public IdentityHashtable collectAndPrepareObjectsForCommit() { 703 IdentityHashtable changedObjects = new IdentityHashtable(1 + getCloneMapping().size()); 704 705 if (! getProject().isPureCMP2Project()) { 707 assignSequenceNumbers(); 708 } 709 710 for (Enumeration clonesEnum = getCloneMapping().keys(); clonesEnum.hasMoreElements();) { 714 Object clone = clonesEnum.nextElement(); 715 changedObjects.put(clone, clone); 716 } 717 for (Enumeration unregisteredNewObjectsEnum = getUnregisteredNewObjects().keys(); 718 unregisteredNewObjectsEnum.hasMoreElements();) { 719 Object newObject = unregisteredNewObjectsEnum.nextElement(); 720 changedObjects.put(newObject, newObject); 721 } 722 723 return changedObjects; 724 } 725 726 730 public IdentityHashtable collectAndPrepareObjectsForNestedMerge() { 731 IdentityHashtable changedObjects = new IdentityHashtable(1 + getCloneMapping().size()); 732 733 discoverAllUnregisteredNewObjects(); 734 735 for (Enumeration clonesEnum = getCloneMapping().keys(); clonesEnum.hasMoreElements();) { 739 Object clone = clonesEnum.nextElement(); 740 changedObjects.put(clone, clone); 741 } 742 for (Enumeration unregisteredNewObjectsEnum = getUnregisteredNewObjects().keys(); 743 unregisteredNewObjectsEnum.hasMoreElements();) { 744 Object newObject = unregisteredNewObjectsEnum.nextElement(); 745 changedObjects.put(newObject, newObject); 746 } 747 748 return changedObjects; 749 } 750 751 767 public void commit() throws DatabaseException, OptimisticLockException { 768 if (!isActive()) { 770 throw ValidationException.cannotCommitUOWAgain(); 771 } 772 if (isAfterWriteChangesFailed()) { 773 throw ValidationException.unitOfWorkAfterWriteChangesFailed("commit"); 774 } 775 776 if (!isNestedUnitOfWork()) { 777 if (isSynchronized()) { 778 if (getParent().wasJTSTransactionInternallyStarted()) { 780 commitInternallyStartedExternalTransaction(); 781 } 782 783 return; 785 } 786 } 787 if (getLifecycle() == CommitTransactionPending) { 788 commitAfterWriteChanges(); 789 return; 790 } 791 log(SessionLog.FINER, SessionLog.TRANSACTION, "begin_unit_of_work_commit"); getEventManager().preCommitUnitOfWork(); 793 setLifecycle(CommitPending); 794 commitRootUnitOfWork(); 795 getEventManager().postCommitUnitOfWork(); 796 log(SessionLog.FINER, SessionLog.TRANSACTION, "end_unit_of_work_commit"); 797 release(); 798 } 799 800 816 public void commitAndResume() throws DatabaseException, OptimisticLockException { 817 if (!isActive()) { 819 throw ValidationException.cannotCommitUOWAgain(); 820 } 821 822 if (isAfterWriteChangesFailed()) { 823 throw ValidationException.unitOfWorkAfterWriteChangesFailed("commit"); 824 } 825 826 if (!isNestedUnitOfWork()) { 827 if (isSynchronized()) { 828 throw ValidationException.cannotCommitAndResumeSynchronizedUOW(this); 833 } 834 } 835 if (getLifecycle() == CommitTransactionPending) { 836 commitAndResumeAfterWriteChanges(); 837 return; 838 } 839 log(SessionLog.FINER, SessionLog.TRANSACTION, "begin_unit_of_work_commit"); getEventManager().preCommitUnitOfWork(); 841 setLifecycle(CommitPending); 842 commitRootUnitOfWork(); 843 getEventManager().postCommitUnitOfWork(); 844 log(SessionLog.FINER, SessionLog.TRANSACTION, "end_unit_of_work_commit"); 845 846 log(SessionLog.FINER, SessionLog.TRANSACTION, "resume_unit_of_work"); 847 synchronizeAndResume(); 848 getEventManager().postResumeUnitOfWork(); 849 } 850 851 857 public void commitAndResumeWithPreBuiltChangeSet(UnitOfWorkChangeSet uowChangeSet) throws DatabaseException, OptimisticLockException { 858 if (!isNestedUnitOfWork()) { 859 if (isSynchronized()) { 860 if (getParent().wasJTSTransactionInternallyStarted()) { 862 commitInternallyStartedExternalTransaction(); 863 } 864 865 return; 867 } 868 } 869 log(SessionLog.FINER, SessionLog.TRANSACTION, "begin_unit_of_work_commit"); getEventManager().preCommitUnitOfWork(); 871 setLifecycle(CommitPending); 872 commitRootUnitOfWorkWithPreBuiltChangeSet(uowChangeSet); 873 getEventManager().postCommitUnitOfWork(); 874 log(SessionLog.FINER, SessionLog.TRANSACTION, "end_unit_of_work_commit"); 875 log(SessionLog.FINER, SessionLog.TRANSACTION, "resume_unit_of_work"); 876 877 synchronizeAndResume(); 878 getEventManager().postResumeUnitOfWork(); 879 } 880 881 897 public void commitAndResumeOnFailure() throws DatabaseException, OptimisticLockException { 898 IdentityMapManager failureManager = (IdentityMapManager)getIdentityMapAccessorInstance().getIdentityMapManager().clone(); 900 try { 901 commitAndResume(); 906 } catch (RuntimeException exception) { 907 setUnitOfWorkChangeSet(null); 909 getIdentityMapAccessorInstance().setIdentityMapManager(failureManager); 910 log(SessionLog.FINER, SessionLog.TRANSACTION, "resuming_unit_of_work_from_failure"); 911 throw exception; 912 } 913 } 914 915 922 protected void commitAfterWriteChanges() { 923 commitTransactionAfterWriteChanges(); 924 mergeClonesAfterCompletion(); 925 setDead(); 926 release(); 927 } 928 929 936 protected void commitAndResumeAfterWriteChanges() { 937 commitTransactionAfterWriteChanges(); 938 mergeClonesAfterCompletion(); 939 log(SessionLog.FINER, SessionLog.TRANSACTION, "resume_unit_of_work"); 940 synchronizeAndResume(); 941 getEventManager().postResumeUnitOfWork(); 942 } 943 944 949 protected boolean commitInternallyStartedExternalTransaction() { 950 boolean committed = false; 951 if (!getParent().isInTransaction() || (wasTransactionBegunPrematurely() && (getParent().getTransactionMutex().getDepth() == 1))) { 952 committed = getParent().commitExternalTransaction(); 953 } 954 return committed; 955 } 956 957 961 public void commitRootUnitOfWork() throws DatabaseException, OptimisticLockException { 962 commitToDatabaseWithChangeSet(true); 963 964 mergeChangesIntoParent(); 966 } 967 968 973 public void commitRootUnitOfWorkWithPreBuiltChangeSet(UnitOfWorkChangeSet uowChangeSet) throws DatabaseException, OptimisticLockException { 974 commitToDatabaseWithPreBuiltChangeSet(uowChangeSet, true); 976 977 mergeChangesIntoParent(); 979 } 980 981 987 protected void commitToDatabase(boolean commitTransaction) { 988 try { 989 if (wasTransactionBegunPrematurely()) { 991 setWasTransactionBegunPrematurely(false); 993 } else { 994 beginTransaction(); 995 } 996 997 if(commitTransaction) { 998 setWasNonObjectLevelModifyQueryExecuted(false); 999 } 1000 1001 Vector deletedObjects = null; if (hasDeletedObjects()) { 1003 deletedObjects = new Vector(getDeletedObjects().size()); 1004 for (Enumeration objects = getDeletedObjects().keys(); objects.hasMoreElements();) { 1005 deletedObjects.addElement(objects.nextElement()); 1006 } 1007 } 1008 1009 if (shouldPerformDeletesFirst) { 1010 if (hasDeletedObjects()) { 1011 getCommitManager().deleteAllObjects(deletedObjects); 1013 1014 for (Enumeration objects = getObjectsDeletedDuringCommit().keys(); 1016 objects.hasMoreElements();) { 1017 oracle.toplink.essentials.internal.sessions.ObjectChangeSet objectChangeSet = (oracle.toplink.essentials.internal.sessions.ObjectChangeSet)this.unitOfWorkChangeSet.getObjectChangeSetForClone(objects.nextElement()); 1018 if (objectChangeSet != null) { 1019 objectChangeSet.clear(); 1020 } 1021 } 1022 } 1023 1024 super.writeAllObjectsWithChangeSet(this.unitOfWorkChangeSet); 1026 issueModifyAllQueryList(); 1028 } else { 1029 super.writeAllObjectsWithChangeSet(this.unitOfWorkChangeSet); 1031 if (hasDeletedObjects()) { 1032 getCommitManager().deleteAllObjects(deletedObjects); 1034 } 1035 1036 issueModifyAllQueryList(); 1038 } 1039 1040 getEventManager().prepareUnitOfWork(); 1042 1043 if (commitTransaction) { 1046 try{ 1047 if (getDatasourceLogin().shouldSynchronizeObjectLevelReadWriteDatabase()){ 1049 setMergeManager(new MergeManager(this)); 1050 getParent().getIdentityMapAccessorInstance().getWriteLockManager().acquireRequiredLocks(getMergeManager(), (UnitOfWorkChangeSet)getUnitOfWorkChangeSet()); 1052 } 1053 commitTransaction(); 1054 }catch (RuntimeException throwable){ 1055 if (getDatasourceLogin().shouldSynchronizeObjectLevelReadWriteDatabase() && (getMergeManager() != null)) { 1056 getParent().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(getMergeManager()); 1058 this.setMergeManager(null); 1059 } 1060 throw throwable; 1061 }catch (Error throwable){ 1062 if (getDatasourceLogin().shouldSynchronizeObjectLevelReadWriteDatabase() && (getMergeManager() != null)) { 1063 getParent().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(getMergeManager()); 1065 this.setMergeManager(null); 1066 } 1067 throw throwable; 1068 } 1069 }else{ 1070 setWasTransactionBegunPrematurely(true); 1071 } 1072 1073 } catch (RuntimeException exception) { 1074 rollbackTransaction(commitTransaction); 1075 if (hasExceptionHandler()) { 1076 getExceptionHandler().handleException(exception); 1077 } else { 1078 throw exception; 1079 } 1080 } 1081 } 1082 1083 1089 protected void commitToDatabaseWithChangeSet(boolean commitTransaction) throws DatabaseException, OptimisticLockException { 1090 try { 1091 startOperationProfile(SessionProfiler.UowCommit); 1092 getCommitManager().setIsActive(true); 1097 IdentityHashtable allObjects = collectAndPrepareObjectsForCommit(); 1099 1100 setAllClonesCollection((IdentityHashtable)allObjects.clone()); 1103 if (getUnitOfWorkChangeSet() == null) { 1106 setUnitOfWorkChangeSet(new UnitOfWorkChangeSet()); 1107 } 1108 calculateChanges(getAllClones(), (UnitOfWorkChangeSet)getUnitOfWorkChangeSet()); 1109 1110 if (hasModifications()) { 1112 commitToDatabase(commitTransaction); 1113 } else { 1114 if (wasTransactionBegunPrematurely()) { 1116 if (commitTransaction) { 1117 setWasTransactionBegunPrematurely(false); 1119 setWasNonObjectLevelModifyQueryExecuted(false); 1120 commitTransaction(); 1121 } 1122 } 1123 getCommitManager().setIsActive(false); 1124 } 1125 endOperationProfile(SessionProfiler.UowCommit); 1126 } catch (RuntimeException exception) { 1127 handleException((RuntimeException )exception); 1128 } 1129 } 1130 1131 1135 protected void commitToDatabaseWithPreBuiltChangeSet(UnitOfWorkChangeSet uowChangeSet, boolean commitTransaction) throws DatabaseException, OptimisticLockException { 1136 try { 1137 getCommitManager().setIsActive(true); 1142 setAllClonesCollection(new IdentityHashtable()); 1144 setUnitOfWorkChangeSet(uowChangeSet); 1146 commitToDatabase(commitTransaction); 1147 1148 } catch (RuntimeException exception) { 1149 handleException((RuntimeException )exception); 1150 } 1151 } 1152 1153 1158 public void commitTransaction() throws DatabaseException { 1159 getParent().commitTransaction(); 1160 } 1161 1162 1167 protected void commitTransactionAfterWriteChanges() { 1168 setWasNonObjectLevelModifyQueryExecuted(false); 1169 if (hasModifications() || wasTransactionBegunPrematurely()) { 1170 try{ 1171 if (getDatasourceLogin().shouldSynchronizeObjectLevelReadWriteDatabase() && (getUnitOfWorkChangeSet() != null)) { 1173 setMergeManager(new MergeManager(this)); 1174 getParent().getIdentityMapAccessorInstance().getWriteLockManager().acquireRequiredLocks(getMergeManager(), (UnitOfWorkChangeSet)getUnitOfWorkChangeSet()); 1176 } 1177 setWasTransactionBegunPrematurely(false); 1178 commitTransaction(); 1179 }catch (RuntimeException exception){ 1180 if (getDatasourceLogin().shouldSynchronizeObjectLevelReadWriteDatabase() && (getMergeManager() != null)) { 1181 getParent().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(getMergeManager()); 1183 this.setMergeManager(null); 1184 } 1185 rollbackTransaction(); 1186 release(); 1187 handleException(exception); 1188 }catch (Error throwable){ 1189 if (getDatasourceLogin().shouldSynchronizeObjectLevelReadWriteDatabase() && (getMergeManager() != null)) { 1190 getParent().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(getMergeManager()); 1192 this.setMergeManager(null); 1193 } 1194 throw throwable; 1195 } 1196 } 1197 } 1198 1199 1203 public Vector copyReadOnlyClasses() { 1205 return Helper.buildVectorFromHashtableElements(getReadOnlyClasses()); 1206 } 1207 1208 1222 public Object deepMergeClone(Object rmiClone) { 1223 return mergeClone(rmiClone, MergeManager.CASCADE_ALL_PARTS); 1224 } 1225 1226 1235 public Object deepRevertObject(Object clone) { 1236 return revertObject(clone, MergeManager.CASCADE_ALL_PARTS); 1237 } 1238 1239 1246 public void deepUnregisterObject(Object clone) { 1247 unregisterObject(clone, DescriptorIterator.CascadeAllParts); 1248 } 1249 1250 1255 public void deleteAllObjects(Vector domainObjects) { 1256 for (Enumeration objectsEnum = domainObjects.elements(); objectsEnum.hasMoreElements();) { 1258 deleteObject(objectsEnum.nextElement()); 1259 } 1260 } 1261 1262 1268 protected void discoverAllUnregisteredNewObjects() { 1269 IdentityHashtable visitedNodes = new IdentityHashtable(); 1271 IdentityHashtable newObjects = new IdentityHashtable(); 1272 IdentityHashtable existingObjects = new IdentityHashtable(); 1273 1274 for (Enumeration clonesEnum = getCloneMapping().keys(); clonesEnum.hasMoreElements();) { 1276 Object clone = clonesEnum.nextElement(); 1277 discoverUnregisteredNewObjects(clone, newObjects, existingObjects, visitedNodes); 1278 } 1279 1280 setUnregisteredNewObjects(newObjects); 1281 setUnregisteredExistingObjects(existingObjects); 1282 } 1283 1284 1288 public void discoverUnregisteredNewObjects(Object clone, IdentityHashtable knownNewObjects, IdentityHashtable unregisteredExistingObjects, IdentityHashtable visitedObjects) { 1289 DescriptorIterator iterator = new DescriptorIterator() { 1291 public void iterate(Object object) { 1292 if (isClassReadOnly(object.getClass(), this.getCurrentDescriptor())) { 1294 this.setShouldBreak(true); 1295 return; 1296 } 1297 1298 1301 if (isSmartMerge() && isOriginalNewObject(object)) { 1302 return; 1303 } else if (!isObjectRegistered(object)) { if ((shouldPerformNoValidation()) && (checkForUnregisteredExistingObject(object))) { 1305 ((IdentityHashtable)getUnregisteredExistingObjects()).put(object, object); 1309 this.setShouldBreak(true); 1310 return; 1311 1312 } 1313 1314 ((IdentityHashtable)getResult()).put(object, object); 1316 } 1317 } 1318 }; 1319 1320 setUnregisteredExistingObjects(unregisteredExistingObjects); 1322 1323 iterator.setVisitedObjects(visitedObjects); 1324 iterator.setResult(knownNewObjects); 1325 iterator.setSession(this); 1326 iterator.setShouldIterateOverWrappedObjects(false); 1330 iterator.startIterationOn(clone); 1331 } 1332 1333 1343 public void dontPerformValidation() { 1344 setValidationLevel(None); 1345 } 1346 1347 1352 public Object executeCall(Call call, AbstractRecord translationRow, DatabaseQuery query) throws DatabaseException { 1353 Accessor accessor; 1354 if (query.getSessionName() == null) { 1355 accessor = query.getSession().getAccessor(query.getReferenceClass()); 1356 } else { 1357 accessor = query.getSession().getAccessor(query.getSessionName()); 1358 } 1359 1360 query.setAccessor(accessor); 1361 try { 1362 return query.getAccessor().executeCall(call, translationRow, this); 1363 } finally { 1364 if (call.isFinished()) { 1365 query.setAccessor(null); 1366 } 1367 } 1368 } 1369 1370 1383 public void forceUpdateToVersionField(Object lockObject, boolean shouldModifyVersionField) { 1384 ClassDescriptor descriptor = getDescriptor(lockObject); 1385 if (descriptor == null) { 1386 throw DescriptorException.missingDescriptor(lockObject.getClass().toString()); 1387 } 1388 getOptimisticReadLockObjects().put(descriptor.getObjectBuilder().unwrapObject(lockObject, this), new Boolean (shouldModifyVersionField)); 1389 } 1390 1391 1395 public Accessor getAccessor() { 1396 return getParent().getAccessor(); 1397 } 1398 1399 1404 public CommitManager getCommitManager() { 1405 if (commitManager == null) { 1407 commitManager = new CommitManager(this); 1408 commitManager.setCommitOrder(getParent().getCommitManager().getCommitOrder()); 1410 } 1411 return commitManager; 1412 } 1413 1414 1418 public Accessor getAccessor(Class domainClass) { 1419 return getParent().getAccessor(domainClass); 1420 } 1421 1422 1426 public Accessor getAccessor(String sessionName) { 1427 return getParent().getAccessor(sessionName); 1428 } 1429 1430 1435 public oracle.toplink.essentials.sessions.UnitOfWork getActiveUnitOfWork() { 1436 1437 1441 return getParent().getActiveUnitOfWork(); 1442 } 1443 1444 1449 protected IdentityHashtable getAllClones() { 1450 return this.allClones; 1451 } 1452 1453 1458 public Vector getAllFromNewObjects(Expression selectionCriteria, Class theClass, AbstractRecord translationRow, InMemoryQueryIndirectionPolicy valueHolderPolicy) { 1459 if (shouldNewObjectsBeCached()) { 1461 return new Vector(1); 1462 } 1463 1464 if (!hasNewObjects()) { 1466 return new Vector(1); 1467 } 1468 1469 Vector objects = new Vector(); 1470 for (Enumeration newObjectsEnum = getNewObjectsOriginalToClone().elements(); 1471 newObjectsEnum.hasMoreElements();) { 1472 Object object = newObjectsEnum.nextElement(); 1473 if (theClass.isInstance(object)) { 1474 if (selectionCriteria == null) { 1475 objects.addElement(object); 1476 } else if (selectionCriteria.doesConform(object, this, translationRow, valueHolderPolicy)) { 1477 objects.addElement(object); 1478 } 1479 } 1480 } 1481 return objects; 1482 } 1483 1484 1488 public Object getBackupClone(Object clone) throws QueryException { 1489 Object backupClone = getCloneMapping().get(clone); 1490 if (backupClone != null) { 1491 return backupClone; 1492 } 1493 1494 1497 if (isObjectRegistered(clone)) { 1498 return getCloneMapping().get(clone); 1499 1500 } else { 1501 ClassDescriptor descriptor = getDescriptor(clone); 1502 Vector primaryKey = keyFromObject(clone, descriptor); 1503 1504 if (getParent().getIdentityMapAccessorInstance().containsObjectInIdentityMap(primaryKey, clone.getClass(), descriptor)) { 1506 if ((getUnregisteredNewObjects().get(clone) != null) && isMergePending()) { 1508 return descriptor.getObjectBuilder().buildNewInstance(); 1512 } 1513 if (hasObjectsDeletedDuringCommit() && getObjectsDeletedDuringCommit().containsKey(clone)) { 1514 throw QueryException.backupCloneIsDeleted(clone); 1515 } 1516 throw QueryException.backupCloneIsOriginalFromParent(clone); 1517 } 1518 else if (hasNewObjects() && getNewObjectsOriginalToClone().containsKey(clone)) { 1521 1522 1525 if (isSmartMerge()) { 1526 backupClone = getCloneMapping().get(getNewObjectsOriginalToClone().get(clone)); 1527 1528 } else { 1529 throw QueryException.backupCloneIsOriginalFromSelf(clone); 1530 } 1531 } else { 1532 backupClone = descriptor.getObjectBuilder().buildNewInstance(); 1534 } 1535 } 1536 1537 return backupClone; 1538 } 1539 1540 1544 public Object getBackupCloneForCommit(Object clone) { 1545 Object backupClone = getBackupClone(clone); 1546 1547 1550 if (isCloneNewObject(clone)) { 1551 return getDescriptor(clone).getObjectBuilder().buildNewInstance(); 1552 } 1553 1554 return backupClone; 1555 } 1556 1557 1564 public oracle.toplink.essentials.changesets.UnitOfWorkChangeSet getCurrentChanges() { 1565 IdentityHashtable allObjects = null; 1566 allObjects = collectAndPrepareObjectsForNestedMerge(); 1567 return calculateChanges(allObjects, new UnitOfWorkChangeSet()); 1568 } 1569 1570 1586 public AbstractSession getParentIdentityMapSession(DatabaseQuery query, boolean canReturnSelf, boolean terminalOnly) { 1587 if (canReturnSelf && !terminalOnly) { 1588 return this; 1589 } else { 1590 return getParent().getParentIdentityMapSession(query, true, terminalOnly); 1591 } 1592 } 1593 1594 1609 public AbstractSession getExecutionSession(DatabaseQuery query) { 1610 1616 return getParent().getExecutionSession(query); 1621 } 1622 1623 1631 public IdentityHashtable getCloneMapping() { 1632 if (cloneMapping == null) { 1634 cloneMapping = new IdentityHashtable(); 1636 } 1637 return cloneMapping; 1638 } 1639 1640 protected boolean hasCloneMapping() { 1641 return ((cloneMapping != null) && !cloneMapping.isEmpty()); 1642 } 1643 1644 1650 public IdentityHashtable getCloneToOriginals() { 1651 if (cloneToOriginals == null) { cloneToOriginals = new IdentityHashtable(); 1655 } 1656 return cloneToOriginals; 1657 } 1658 1659 protected boolean hasCloneToOriginals() { 1660 return ((cloneToOriginals != null) && !cloneToOriginals.isEmpty()); 1661 } 1662 1663 1669 public boolean hasNewObjects() { 1670 return ((newObjectsOriginalToClone != null) && !newObjectsOriginalToClone.isEmpty()); 1671 } 1672 1673 1678 public Vector getDefaultReadOnlyClasses() { 1679 return getParent().getDefaultReadOnlyClasses(); 1680 } 1681 1682 1687 public IdentityHashtable getDeletedObjects() { 1688 if (deletedObjects == null) { 1689 deletedObjects = new IdentityHashtable(); 1691 } 1692 return deletedObjects; 1693 } 1694 1695 protected boolean hasDeletedObjects() { 1696 return ((deletedObjects != null) && !deletedObjects.isEmpty()); 1697 } 1698 1699 1705 public ClassDescriptor getDescriptorForAlias(String alias) { 1706 return getParent().getDescriptorForAlias(alias); 1707 } 1708 1709 1715 public Map getDescriptors() { 1716 return getParent().getDescriptors(); 1717 } 1718 1719 1723 public int getLifecycle() { 1724 return lifecycle; 1725 } 1726 1727 1731 public MergeManager getMergeManager() { 1732 return this.lastUsedMergeManager; 1733 } 1734 1735 1739 public IdentityHashtable getNewAggregates() { 1740 if (this.newAggregates == null) { 1741 this.newAggregates = new IdentityHashtable(); 1743 } 1744 return newAggregates; 1745 } 1746 1747 1752 public synchronized IdentityHashtable getNewObjectsCloneToOriginal() { 1753 if (newObjectsCloneToOriginal == null) { 1754 newObjectsCloneToOriginal = new IdentityHashtable(); 1756 } 1757 return newObjectsCloneToOriginal; 1758 } 1759 1760 1765 public synchronized IdentityHashtable getNewObjectsOriginalToClone() { 1766 if (newObjectsOriginalToClone == null) { 1767 newObjectsOriginalToClone = new IdentityHashtable(); 1769 } 1770 return newObjectsOriginalToClone; 1771 } 1772 1773 1777 public Sequencing getSequencing() { 1778 return getParent().getSequencing(); 1779 } 1780 1781 1787 public ServerPlatform getServerPlatform(){ 1788 return getParent().getServerPlatform(); 1789 } 1790 1791 1802 public String getSessionTypeString() { 1803 return "UnitOfWork"; 1804 } 1805 1806 1810 public void afterTransaction(boolean committed, boolean isExternalTransaction) { 1811 if (!committed && isExternalTransaction) { 1812 getParent().setWasJTSTransactionInternallyStarted(false); 1815 setLifecycle(AfterExternalTransactionRolledBack); 1817 } 1818 if ((getMergeManager() != null) && (getMergeManager().getAcquiredLocks() != null) && (!getMergeManager().getAcquiredLocks().isEmpty())) { 1819 getParent().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(getMergeManager()); 1821 this.setMergeManager(null); 1822 } 1823 getParent().afterTransaction(committed, isExternalTransaction); 1824 } 1825 1826 1831 public Object getObjectFromNewObjects(Class theClass, Vector selectionKey) { 1832 if (!hasNewObjects()) { 1834 return null; 1835 } 1836 ObjectBuilder objectBuilder = getDescriptor(theClass).getObjectBuilder(); 1837 for (Enumeration newObjectsEnum = getNewObjectsOriginalToClone().elements(); 1838 newObjectsEnum.hasMoreElements();) { 1839 Object object = newObjectsEnum.nextElement(); 1840 if (theClass.isInstance(object)) { 1841 Vector primaryKey = objectBuilder.extractPrimaryKeyFromObject(object, this); 1843 if (new CacheKey(primaryKey).equals(new CacheKey(selectionKey))) { 1844 return object; 1845 } 1846 } 1847 } 1848 return null; 1849 } 1850 1851 1856 public Object getObjectFromNewObjects(Expression selectionCriteria, Class theClass, AbstractRecord translationRow, InMemoryQueryIndirectionPolicy valueHolderPolicy) { 1857 if (!hasNewObjects()) { 1859 return null; 1860 } 1861 for (Enumeration newObjectsEnum = getNewObjectsOriginalToClone().elements(); 1862 newObjectsEnum.hasMoreElements();) { 1863 Object object = newObjectsEnum.nextElement(); 1864 if (theClass.isInstance(object)) { 1865 if (selectionCriteria == null) { 1866 return object; 1867 } 1868 if (selectionCriteria.doesConform(object, this, translationRow, valueHolderPolicy)) { 1869 return object; 1870 } 1871 } 1872 } 1873 return null; 1874 } 1875 1876 1880 public IdentityHashtable getObjectsDeletedDuringCommit() { 1881 if (objectsDeletedDuringCommit == null) { 1883 objectsDeletedDuringCommit = new IdentityHashtable(); 1885 } 1886 return objectsDeletedDuringCommit; 1887 } 1888 1889 protected boolean hasObjectsDeletedDuringCommit() { 1890 return ((objectsDeletedDuringCommit != null) && !objectsDeletedDuringCommit.isEmpty()); 1891 } 1892 1893 1897 public Hashtable getOptimisticReadLockObjects() { 1898 if (optimisticReadLockObjects == null) { 1899 optimisticReadLockObjects = new Hashtable(2); 1900 } 1901 return optimisticReadLockObjects; 1902 } 1903 1904 1908 public Object getOriginalVersionOfNewObject(Object workingClone) { 1909 if (!hasNewObjects()) { 1911 return null; 1912 } 1913 return getNewObjectsCloneToOriginal().get(workingClone); 1914 } 1915 1916 1920 public Object getOriginalVersionOfObject(Object workingClone) { 1921 if (workingClone == null) { 1923 return null; 1924 } 1925 ClassDescriptor descriptor = getDescriptor(workingClone); 1926 ObjectBuilder builder = descriptor.getObjectBuilder(); 1927 Object implementation = builder.unwrapObject(workingClone, this); 1928 1929 Vector primaryKey = builder.extractPrimaryKeyFromObject(implementation, this); 1930 Object original = getParent().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, implementation.getClass(), descriptor, null); 1931 1932 if (original == null) { 1933 original = getOriginalVersionOfNewObject(implementation); 1935 } 1936 1937 if (original == null) { 1938 if (isClassReadOnly(implementation.getClass(), descriptor)) { 1941 return implementation; 1942 } 1943 1944 if (hasCloneToOriginals()) { 1947 original = getCloneToOriginals().get(workingClone); 1948 } 1949 } 1950 1951 if (original == null) { 1952 original = buildOriginal(implementation); 1954 } 1955 1956 return original; 1957 } 1958 1959 1963 public Object getOriginalVersionOfObjectOrNull(Object workingClone) { 1964 if (workingClone == null) { 1966 return null; 1967 } 1968 ClassDescriptor descriptor = getDescriptor(workingClone); 1969 ObjectBuilder builder = descriptor.getObjectBuilder(); 1970 Object implementation = builder.unwrapObject(workingClone, this); 1971 1972 Vector primaryKey = builder.extractPrimaryKeyFromObject(implementation, this); 1973 Object original = getParent().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, implementation.getClass(), descriptor, null); 1974 1975 if (original == null) { 1976 original = getOriginalVersionOfNewObject(implementation); 1978 } 1979 1980 if (original == null) { 1981 if (isClassReadOnly(implementation.getClass(), descriptor)) { 1984 return implementation; 1985 } 1986 1987 if (hasCloneToOriginals()) { 1990 original = getCloneToOriginals().get(workingClone); 1991 } 1992 } 1993 return original; 1994 } 1995 1996 2001 public AbstractSession getParent() { 2002 return parent; 2003 } 2004 2005 2009 public Platform getPlatform(Class domainClass) { 2010 return getParent().getPlatform(domainClass); 2011 } 2012 2013 2017 public int getShouldThrowConformExceptions() { 2018 return shouldThrowConformExceptions; 2019 } 2020 2021 2026 public DatabaseQuery getQuery(String name, Vector arguments) { 2027 DatabaseQuery query = super.getQuery(name, arguments); 2028 if (query == null) { 2029 query = getParent().getQuery(name, arguments); 2030 } 2031 2032 return query; 2033 } 2034 2035 2040 public DatabaseQuery getQuery(String name) { 2041 DatabaseQuery query = super.getQuery(name); 2042 if (query == null) { 2043 query = getParent().getQuery(name); 2044 } 2045 2046 return query; 2047 } 2048 2049 2057 public Hashtable getReadOnlyClasses() { 2058 return readOnlyClasses; 2059 } 2060 2061 2066 protected IdentityHashtable getRemovedObjects() { 2067 if (removedObjects == null) { 2069 removedObjects = new IdentityHashtable(); 2071 } 2072 return removedObjects; 2073 } 2074 2075 protected boolean hasRemovedObjects() { 2076 return ((removedObjects != null) && !removedObjects.isEmpty()); 2077 } 2078 2079 protected boolean hasModifyAllQueries() { 2080 return ((modifyAllQueries != null) && !modifyAllQueries.isEmpty()); 2081 } 2082 2083 protected boolean hasDeferredModifyAllQueries() { 2084 return ((deferredModifyAllQueries != null) && !deferredModifyAllQueries.isEmpty()); 2085 } 2086 2087 2091 public int getState() { 2092 return lifecycle; 2093 } 2094 2095 2100 public Object getTransaction() { 2101 return transaction; 2102 } 2103 2104 2109 public void setTransaction(Object transaction) { 2110 this.transaction = transaction; 2111 } 2112 2113 2118 public oracle.toplink.essentials.changesets.UnitOfWorkChangeSet getUnitOfWorkChangeSet() { 2119 return unitOfWorkChangeSet; 2120 } 2121 2122 2127 public oracle.toplink.essentials.internal.helper.IdentityHashtable getUnregisteredExistingObjects() { 2128 if (this.unregisteredExistingObjects == null) { 2129 this.unregisteredExistingObjects = new IdentityHashtable(); 2131 } 2132 return unregisteredExistingObjects; 2133 } 2134 2135 2140 protected IdentityHashtable getUnregisteredNewObjects() { 2141 if (unregisteredNewObjects == null) { 2142 unregisteredNewObjects = new IdentityHashtable(); 2144 } 2145 return unregisteredNewObjects; 2146 } 2147 2148 2158 public int getValidationLevel() { 2159 return validationLevel; 2160 } 2161 2162 2167 public boolean hasChanges() { 2168 if (hasNewObjects()) { 2169 return true; 2170 } 2171 IdentityHashtable allObjects = collectAndPrepareObjectsForNestedMerge(); 2172 2173 if (!getUnregisteredNewObjects().isEmpty()) { 2175 return true; 2176 } 2177 if (hasDeletedObjects()) { 2178 return true; 2179 } 2180 UnitOfWorkChangeSet changeSet = calculateChanges(allObjects, new UnitOfWorkChangeSet()); 2181 return changeSet.hasChanges(); 2182 } 2183 2184 2192 protected boolean hasModifications() { 2193 if (getUnitOfWorkChangeSet().hasChanges() || hasDeletedObjects() || hasModifyAllQueries() || hasDeferredModifyAllQueries() || ((oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet)getUnitOfWorkChangeSet()).hasForcedChanges()) { 2194 return true; 2195 } else { 2196 return false; 2197 } 2198 } 2199 2200 2205 public void initializeIdentityMapAccessor() { 2206 this.identityMapAccessor = new UnitOfWorkIdentityMapAccessor(this, new IdentityMapManager(this)); 2207 } 2208 2209 2214 public Object internalExecuteQuery(DatabaseQuery query, AbstractRecord databaseRow) throws DatabaseException, QueryException { 2215 if (!isActive()) { 2216 throw QueryException.querySentToInactiveUnitOfWork(query); 2217 } 2218 return query.executeInUnitOfWork(this, databaseRow); 2219 } 2220 2221 2227 public Object internalRegisterObject(Object object, ClassDescriptor descriptor) { 2228 if (object == null) { 2229 return null; 2230 } 2231 if (descriptor.isAggregateDescriptor() || descriptor.isAggregateCollectionDescriptor()) { 2232 throw ValidationException.cannotRegisterAggregateObjectInUnitOfWork(object.getClass()); 2233 } 2234 Object registeredObject = checkIfAlreadyRegistered(object, descriptor); 2235 if (registeredObject == null) { 2236 registeredObject = checkExistence(object); 2237 if (registeredObject == null) { 2238 registeredObject = cloneAndRegisterNewObject(object); 2241 } 2242 } 2243 return registeredObject; 2244 } 2245 2246 2250 public boolean isActive() { 2251 return !isDead(); 2252 } 2253 2254 2260 public boolean isClassReadOnly(Class theClass, ClassDescriptor descriptor) { 2261 if ((descriptor != null) && (descriptor.shouldBeReadOnly())) { 2262 return true; 2263 } 2264 if ((theClass != null) && getReadOnlyClasses().containsKey(theClass)) { 2265 return true; 2266 } 2267 return false; 2268 } 2269 2270 2274 public boolean isCloneNewObject(Object clone) { 2275 if (!hasNewObjects()) { 2277 return false; 2278 } 2279 return getNewObjectsCloneToOriginal().containsKey(clone); 2280 } 2281 2282 2286 public boolean isCommitPending() { 2287 return getLifecycle() == CommitPending; 2288 } 2289 2290 2294 public boolean isDead() { 2295 return getLifecycle() == Death; 2296 } 2297 2298 2302 public boolean isInTransaction() { 2303 return getParent().isInTransaction(); 2304 } 2305 2306 2310 public boolean isMergePending() { 2311 return getLifecycle() == MergePending; 2312 } 2313 2314 2320 public boolean isAfterWriteChangesButBeforeCommit() { 2321 return ((getLifecycle() == CommitTransactionPending) || (getLifecycle() == WriteChangesFailed)); 2322 } 2323 2324 2328 protected boolean isAfterWriteChangesFailed() { 2329 return getLifecycle() == WriteChangesFailed; 2330 } 2331 2332 2336 public boolean isNestedUnitOfWork() { 2337 return false; 2338 } 2339 2340 2344 public boolean isObjectDeleted(Object object) { 2345 boolean isDeleted = false; 2346 if (hasDeletedObjects()) { 2347 isDeleted = getDeletedObjects().containsKey(object); 2348 } 2349 if (getParent().isUnitOfWork()) { 2350 return isDeleted || ((UnitOfWorkImpl)getParent()).isObjectDeleted(object); 2351 } else { 2352 return isDeleted; 2353 } 2354 } 2355 2356 2360 public boolean isObjectNew(Object clone) { 2361 return (isCloneNewObject(clone) || (!isObjectRegistered(clone) && !getReadOnlyClasses().contains(clone.getClass()) && !getUnregisteredExistingObjects().contains(clone))); 2363 } 2364 2365 2369 public boolean isObjectRegistered(Object clone) { 2370 if (getCloneMapping().containsKey(clone)) { 2371 return true; 2372 } 2373 2374 if (isSmartMerge()){ 2376 ClassDescriptor descriptor = getDescriptor(clone); 2377 if (getParent().getIdentityMapAccessorInstance().containsObjectInIdentityMap(keyFromObject(clone, descriptor), clone.getClass(), descriptor) ) { 2378 mergeCloneWithReferences(clone); 2379 2380 return true; 2382 } 2383 } 2384 return false; 2385 } 2386 2387 2393 public boolean isOriginalNewObject(Object original) { 2394 return (hasNewObjects() && getNewObjectsOriginalToClone().containsKey(original)) || getNewAggregates().containsKey(original); 2395 } 2396 2397 2401 public static boolean isSmartMerge() { 2402 return SmartMerge; 2403 } 2404 2405 2410 public void issueSQLbeforeCompletion() { 2411 issueSQLbeforeCompletion(true); 2412 } 2413 2414 2419 public void issueSQLbeforeCompletion(boolean commitTransaction) { 2420 if (getLifecycle() == CommitTransactionPending) { 2421 commitTransactionAfterWriteChanges(); 2422 return; 2423 } 2424 log(SessionLog.FINER, SessionLog.TRANSACTION, "begin_unit_of_work_commit"); 2426 getEventManager().preCommitUnitOfWork(); 2427 setLifecycle(CommitPending); 2428 commitToDatabaseWithChangeSet(commitTransaction); 2429 } 2430 2431 2435 protected void issueModifyAllQueryList() { 2436 if (deferredModifyAllQueries != null) { 2437 for (int i = 0; i < deferredModifyAllQueries.size(); i++) { 2438 Object [] queries = (Object [])deferredModifyAllQueries.get(i); 2439 ModifyAllQuery query = (ModifyAllQuery)queries[0]; 2440 AbstractRecord translationRow = (AbstractRecord)queries[1]; 2441 getParent().executeQuery(query, translationRow); 2442 } 2443 } 2444 } 2445 2446 2450 public boolean isSynchronized() { 2451 return isSynchronized; 2452 } 2453 2454 2458 public boolean isUnitOfWork() { 2459 return true; 2460 } 2461 2462 2465 protected void mergeChangesIntoParent() { 2466 UnitOfWorkChangeSet uowChangeSet = (UnitOfWorkChangeSet)getUnitOfWorkChangeSet(); 2467 if (uowChangeSet == null) { 2468 setUnitOfWorkChangeSet(new UnitOfWorkChangeSet()); 2470 uowChangeSet = (UnitOfWorkChangeSet)getUnitOfWorkChangeSet(); 2471 calculateChanges(getAllClones(), (UnitOfWorkChangeSet)getUnitOfWorkChangeSet()); 2472 } 2473 2474 if (hasModifications()) { 2476 setPendingMerge(); 2477 startOperationProfile(SessionProfiler.Merge); 2478 getParent().getIdentityMapAccessorInstance().acquireWriteLock(); 2480 MergeManager manager = getMergeManager(); 2481 if (manager == null){ 2482 manager = new MergeManager(this); 2484 } 2485 2486 try { 2487 if (!isNestedUnitOfWork()) { 2488 preMergeChanges(); 2489 } 2490 2491 getParent().getEventManager().preMergeUnitOfWorkChangeSet(uowChangeSet); 2494 if (!isNestedUnitOfWork() && getDatasourceLogin().shouldSynchronizeObjectLevelReadWrite()) { 2495 setMergeManager(manager); 2496 getParent().getIdentityMapAccessorInstance().getWriteLockManager().acquireRequiredLocks(getMergeManager(), (UnitOfWorkChangeSet)getUnitOfWorkChangeSet()); 2498 } 2499 Enumeration changeSetLists = ((UnitOfWorkChangeSet)getUnitOfWorkChangeSet()).getObjectChanges().elements(); 2500 while (changeSetLists.hasMoreElements()) { 2501 Hashtable objectChangesList = (Hashtable)((Hashtable)changeSetLists.nextElement()).clone(); 2502 if (objectChangesList != null) { for (Enumeration pendingEnum = objectChangesList.elements(); 2504 pendingEnum.hasMoreElements();) { 2505 ObjectChangeSet changeSetToWrite = (ObjectChangeSet)pendingEnum.nextElement(); 2506 if (changeSetToWrite.hasChanges()) { 2507 Object objectToWrite = changeSetToWrite.getUnitOfWorkClone(); 2508 2509 if (changeSetToWrite.isNew() || (getOriginalVersionOfObjectOrNull(objectToWrite) != null)) { 2511 manager.mergeChanges(objectToWrite, changeSetToWrite); 2512 } 2513 } else { 2514 uowChangeSet.removeObjectChangeSet(changeSetToWrite); 2517 } 2518 } 2519 } 2520 } 2521 2522 if (modifyAllQueries != null) { 2524 for (int i = 0; i < modifyAllQueries.size(); i++) { 2525 ModifyAllQuery query = (ModifyAllQuery)modifyAllQueries.get(i); 2526 query.setSession(getParent()); query.mergeChangesIntoSharedCache(); 2528 } 2529 } 2530 2531 if (isNestedUnitOfWork()) { 2532 changeSetLists = ((UnitOfWorkChangeSet)getUnitOfWorkChangeSet()).getNewObjectChangeSets().elements(); 2533 while (changeSetLists.hasMoreElements()) { 2534 IdentityHashtable objectChangesList = (IdentityHashtable)((IdentityHashtable)changeSetLists.nextElement()).clone(); 2535 if (objectChangesList != null) { for (Enumeration pendingEnum = objectChangesList.elements(); 2537 pendingEnum.hasMoreElements();) { 2538 ObjectChangeSet changeSetToWrite = (ObjectChangeSet)pendingEnum.nextElement(); 2539 if (changeSetToWrite.hasChanges()) { 2540 Object objectToWrite = changeSetToWrite.getUnitOfWorkClone(); 2541 manager.mergeChanges(objectToWrite, changeSetToWrite); 2542 } else { 2543 uowChangeSet.removeObjectChangeSet(changeSetToWrite); 2546 } 2547 } 2548 } 2549 } 2550 } 2551 if (!isNestedUnitOfWork()) { 2552 getParent().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(manager); 2554 setMergeManager(null); 2555 2556 postMergeChanges(); 2557 } 2558 } finally { 2559 if (!isNestedUnitOfWork() && !manager.getAcquiredLocks().isEmpty()) { 2560 getParent().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(manager); 2563 setMergeManager(null); 2564 } 2565 getParent().getIdentityMapAccessorInstance().releaseWriteLock(); 2566 getParent().getEventManager().postMergeUnitOfWorkChangeSet(uowChangeSet); 2567 endOperationProfile(SessionProfiler.Merge); 2568 } 2569 } 2570 } 2571 2572 2586 public Object mergeClone(Object rmiClone) { 2587 return mergeClone(rmiClone, MergeManager.CASCADE_PRIVATE_PARTS); 2588 } 2589 2590 2594 public Object mergeClone(Object rmiClone, int cascadeDepth) { 2595 if (rmiClone == null) { 2596 return null; 2597 } 2598 2599 logDebugMessage(rmiClone, "merge_clone"); 2601 2602 startOperationProfile(SessionProfiler.Merge); 2603 ObjectBuilder builder = getDescriptor(rmiClone).getObjectBuilder(); 2604 Object implementation = builder.unwrapObject(rmiClone, this); 2605 2606 MergeManager manager = new MergeManager(this); 2607 manager.mergeCloneIntoWorkingCopy(); 2608 manager.setCascadePolicy(cascadeDepth); 2609 2610 Object merged = null; 2611 try { 2612 merged = manager.mergeChanges(implementation, null); 2613 } catch (RuntimeException exception) { 2614 merged = handleException(exception); 2615 } 2616 endOperationProfile(SessionProfiler.Merge); 2617 2618 return merged; 2619 } 2620 2621 2625 public void mergeClonesAfterCompletion() { 2626 mergeChangesIntoParent(); 2627 getEventManager().postCommitUnitOfWork(); 2629 log(SessionLog.FINER, SessionLog.TRANSACTION, "end_unit_of_work_commit"); 2630 } 2631 2632 2647 public Object mergeCloneWithReferences(Object rmiClone) { 2648 return this.mergeCloneWithReferences(rmiClone, MergeManager.CASCADE_PRIVATE_PARTS); 2649 } 2650 2651 2652 2667 public Object mergeCloneWithReferences(Object rmiClone, int cascadePolicy) { 2668 2669 if (rmiClone == null) { 2670 return null; 2671 } 2672 ClassDescriptor descriptor = getDescriptor(rmiClone); 2673 if ((descriptor == null) || descriptor.isAggregateDescriptor() || descriptor.isAggregateCollectionDescriptor()) { 2674 if (cascadePolicy == MergeManager.CASCADE_BY_MAPPING){ 2675 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("not_an_entity", new Object []{rmiClone})); 2676 } 2677 return rmiClone; 2678 } 2679 2680 logDebugMessage(rmiClone, "merge_clone_with_references"); 2682 2683 ObjectBuilder builder = descriptor.getObjectBuilder(); 2684 Object implementation = builder.unwrapObject(rmiClone, this); 2685 2686 MergeManager manager = new MergeManager(this); 2687 manager.mergeCloneWithReferencesIntoWorkingCopy(); 2688 manager.setCascadePolicy(cascadePolicy); 2689 Object mergedObject = manager.mergeChanges(implementation, null); 2690 if (isSmartMerge()) { 2691 return builder.wrapObject(mergedObject, this); 2692 } else { 2693 return mergedObject; 2694 } 2695 } 2696 2697 2702 public Object newInstance(Class theClass) { 2703 logDebugMessage(theClass, "new_instance"); 2705 2706 ClassDescriptor descriptor = getDescriptor(theClass); 2707 Object newObject = descriptor.getObjectBuilder().buildNewInstance(); 2708 return registerObject(newObject); 2709 } 2710 2711 2719 public void performRemove(Object toBeDeleted, IdentityHashtable visitedObjects){ 2720 try { 2721 if (toBeDeleted == null) { 2722 return; 2723 } 2724 ClassDescriptor descriptor = getDescriptor(toBeDeleted); 2725 if ((descriptor == null) || descriptor.isAggregateDescriptor() || descriptor.isAggregateCollectionDescriptor()) { 2726 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("not_an_entity", new Object []{toBeDeleted})); 2727 } 2728 logDebugMessage(toBeDeleted, "deleting_object"); 2729 2730 startOperationProfile(SessionProfiler.DeletedObject); 2731 if (getDeletedObjects().contains(toBeDeleted)){ 2733 return; 2734 } 2735 visitedObjects.put(toBeDeleted,toBeDeleted); 2736 Object registeredObject = checkIfAlreadyRegistered(toBeDeleted, descriptor); 2737 if (registeredObject == null) { 2738 Vector primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(toBeDeleted, this); 2739 DoesExistQuery existQuery = descriptor.getQueryManager().getDoesExistQuery(); 2740 existQuery = (DoesExistQuery)existQuery.clone(); 2741 existQuery.setObject(toBeDeleted); 2742 existQuery.setPrimaryKey(primaryKey); 2743 existQuery.setDescriptor(descriptor); 2744 2745 existQuery.setCheckCacheFirst(true); 2746 if (((Boolean )executeQuery(existQuery)).booleanValue()){ 2747 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("cannot_remove_detatched_entity", new Object []{toBeDeleted})); 2748 } }else{ 2750 if (descriptor.getEventManager().hasAnyEventListeners()) { 2752 oracle.toplink.essentials.descriptors.DescriptorEvent event = new oracle.toplink.essentials.descriptors.DescriptorEvent(toBeDeleted); 2753 event.setEventCode(DescriptorEventManager.PreRemoveEvent); 2754 event.setSession(this); 2755 descriptor.getEventManager().executeEvent(event); 2756 } 2757 if (hasNewObjects() && getNewObjectsOriginalToClone().contains(registeredObject)){ 2758 unregisterObject(registeredObject, DescriptorIterator.NoCascading); 2759 }else{ 2760 getDeletedObjects().put(toBeDeleted, toBeDeleted); 2761 } 2762 } 2763 descriptor.getObjectBuilder().cascadePerformRemove(toBeDeleted, this, visitedObjects); 2764 } finally { 2765 endOperationProfile(SessionProfiler.DeletedObject); 2766 } 2767 } 2768 2769 2779 public void performFullValidation() { 2780 setValidationLevel(Full); 2781 2782 } 2783 2784 2794 public void performPartialValidation() { 2795 setValidationLevel(Partial); 2796 } 2797 2798 2804 protected void populateAndRegisterObject(Object original, Object workingClone, Vector primaryKey, ClassDescriptor descriptor, Object writeLockValue, long readTime, JoinedAttributeManager joinedAttributeManager) { 2805 getIdentityMapAccessorInstance().putInIdentityMap(workingClone, primaryKey, writeLockValue, readTime, descriptor); 2807 2808 descriptor.getObjectChangePolicy().setChangeListener(workingClone, this, descriptor); 2813 descriptor.getObjectChangePolicy().dissableEventProcessing(workingClone); 2814 2815 ObjectBuilder builder = descriptor.getObjectBuilder(); 2816 builder.populateAttributesForClone(original, workingClone, this, joinedAttributeManager); 2817 Object backupClone = descriptor.getObjectChangePolicy().buildBackupClone(workingClone, builder, this); 2818 getCloneMapping().put(workingClone, backupClone); 2819 2820 descriptor.getObjectChangePolicy().enableEventProcessing(workingClone); 2821 } 2822 2823 2827 protected void postMergeChanges() { 2828 if (!this.getUnitOfWorkChangeSet().getDeletedObjects().isEmpty()){ 2830 oracle.toplink.essentials.internal.helper.IdentityHashtable deletedObjects = this.getUnitOfWorkChangeSet().getDeletedObjects(); 2831 for (Enumeration removedObjects = deletedObjects.keys(); removedObjects.hasMoreElements(); ) { 2832 ObjectChangeSet removedObjectChangeSet = (ObjectChangeSet) removedObjects.nextElement(); 2833 java.util.Vector primaryKeys = removedObjectChangeSet.getPrimaryKeys(); 2834 getParent().getIdentityMapAccessor().removeFromIdentityMap(primaryKeys, removedObjectChangeSet.getClassType(this)); 2835 } 2836 } 2837 } 2838 2839 2843 protected void preMergeChanges() { 2844 if (hasObjectsDeletedDuringCommit()) { 2845 for (Enumeration removedObjects = getObjectsDeletedDuringCommit().keys(); 2846 removedObjects.hasMoreElements();) { 2847 Object removedObject = removedObjects.nextElement(); 2848 getCloneMapping().remove(removedObject); 2849 getAllClones().remove(removedObject); 2850 if (hasNewObjects()) { 2852 Object referenceObjectToRemove = getNewObjectsCloneToOriginal().get(removedObject); 2853 if (referenceObjectToRemove != null) { 2854 getNewObjectsCloneToOriginal().remove(removedObject); 2855 getNewObjectsOriginalToClone().remove(referenceObjectToRemove); 2856 } 2857 } 2858 } 2859 } 2860 } 2861 2862 2867 public void printRegisteredObjects() { 2868 if (shouldLog(SessionLog.SEVERE, SessionLog.CACHE)) { 2869 basicPrintRegisteredObjects(); 2870 } 2871 } 2872 2873 2878 public Object processDeleteObjectQuery(DeleteObjectQuery deleteQuery) { 2879 if (deleteQuery.getObject() == null) { throw QueryException.objectToModifyNotSpecified(deleteQuery); 2882 } 2883 2884 ClassDescriptor descriptor = getDescriptor(deleteQuery.getObject()); 2885 ObjectBuilder builder = descriptor.getObjectBuilder(); 2886 Object implementation = builder.unwrapObject(deleteQuery.getObject(), this); 2887 2888 if (isClassReadOnly(implementation.getClass(), descriptor)) { 2889 throw QueryException.cannotDeleteReadOnlyObject(implementation); 2890 } 2891 2892 if (isCloneNewObject(implementation)) { 2893 unregisterObject(implementation); 2894 return implementation; 2895 } 2896 Vector primaryKey = builder.extractPrimaryKeyFromObject(implementation, this); 2897 Object clone = getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, implementation.getClass(), descriptor, null); 2898 if (clone == null) { 2899 clone = implementation; 2900 } 2901 2902 clone = builder.unwrapObject(clone, this); 2904 2905 deleteQuery.setObject(clone); 2906 if (!getCommitManager().isActive()) { 2907 getDeletedObjects().put(clone, primaryKey); 2908 return clone; 2909 } else { 2910 if (hasObjectsDeletedDuringCommit()) { 2912 if (getObjectsDeletedDuringCommit().containsKey(clone)) { 2913 return clone; 2914 } 2915 } 2916 } 2917 return null; 2918 } 2919 2920 2924 protected void basicPrintRegisteredObjects() { 2925 String cr = Helper.cr(); 2926 StringWriter writer = new StringWriter(); 2927 writer.write(LoggingLocalization.buildMessage("unitofwork_identity_hashcode", new Object [] { cr, String.valueOf(System.identityHashCode(this)) })); 2928 if (hasDeletedObjects()) { 2929 writer.write(cr + LoggingLocalization.buildMessage("deleted_objects")); 2930 for (Enumeration enumtr = getDeletedObjects().keys(); enumtr.hasMoreElements();) { 2931 Object object = enumtr.nextElement(); 2932 writer.write(LoggingLocalization.buildMessage("key_identity_hash_code_object", new Object [] { cr, Helper.printVector(getDescriptor(object).getObjectBuilder().extractPrimaryKeyFromObject(object, this)), "\t", String.valueOf(System.identityHashCode(object)), object })); 2933 } 2934 } 2935 writer.write(cr + LoggingLocalization.buildMessage("all_registered_clones")); 2936 for (Enumeration enumtr = getCloneMapping().keys(); enumtr.hasMoreElements();) { 2937 Object object = enumtr.nextElement(); 2938 writer.write(LoggingLocalization.buildMessage("key_identity_hash_code_object", new Object [] { cr, Helper.printVector(getDescriptor(object).getObjectBuilder().extractPrimaryKeyFromObject(object, this)), "\t", String.valueOf(System.identityHashCode(object)), object })); 2939 } 2940 log(SessionLog.SEVERE, SessionLog.TRANSACTION, writer.toString(), null, null, false); 2941 } 2942 2943 2954 public Vector registerAllObjects(Collection domainObjects) { 2955 Vector clones = new Vector(domainObjects.size()); 2956 for (Iterator objectsEnum = domainObjects.iterator(); objectsEnum.hasNext();) { 2957 clones.addElement(registerObject(objectsEnum.next())); 2958 } 2959 return clones; 2960 } 2961 2962 2973 public Vector registerAllObjects(Vector domainObjects) throws DatabaseException, OptimisticLockException { 2974 Vector clones = new Vector(domainObjects.size()); 2975 for (Enumeration objectsEnum = domainObjects.elements(); objectsEnum.hasMoreElements();) { 2976 clones.addElement(registerObject(objectsEnum.nextElement())); 2977 } 2978 return clones; 2979 } 2980 2981 2990 public synchronized Object registerExistingObject(Object existingObject, JoinedAttributeManager joinedAttributeManager) { 2991 if (existingObject == null) { 2992 return null; 2993 } 2994 ClassDescriptor descriptor = getDescriptor(existingObject); 2995 if (descriptor == null) { 2996 throw DescriptorException.missingDescriptor(existingObject.getClass().toString()); 2997 } 2998 if (this.isClassReadOnly(descriptor.getJavaClass(), descriptor)) { 2999 return existingObject; 3000 } 3001 3002 ObjectBuilder builder = descriptor.getObjectBuilder(); 3003 Object implementation = builder.unwrapObject(existingObject, this); 3004 Object registeredObject = this.registerExistingObject(implementation, descriptor, joinedAttributeManager); 3005 3006 if (implementation != existingObject) { 3008 return builder.wrapObject(registeredObject, this); 3009 } else { 3010 return registeredObject; 3011 } 3012 } 3013 3014 3023 public synchronized Object registerExistingObject(Object existingObject) { 3024 return registerExistingObject(existingObject, null); 3025 } 3026 3027 3036 protected synchronized Object registerExistingObject(Object objectToRegister, ClassDescriptor descriptor, JoinedAttributeManager joinedAttributeManager) { 3037 if (isAfterWriteChangesButBeforeCommit()) { 3038 throw ValidationException.illegalOperationForUnitOfWorkLifecycle(getLifecycle(), "registerExistingObject"); 3039 } 3040 if (descriptor.isAggregateDescriptor() || descriptor.isAggregateCollectionDescriptor()) { 3041 throw ValidationException.cannotRegisterAggregateObjectInUnitOfWork(objectToRegister.getClass()); 3042 } 3043 logDebugMessage(objectToRegister, "register_existing"); 3045 Object registeredObject; 3046 try { 3047 startOperationProfile(SessionProfiler.Register); 3048 registeredObject = checkIfAlreadyRegistered(objectToRegister, descriptor); 3049 if (registeredObject == null) { 3050 Vector primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(objectToRegister, this); 3053 3054 registeredObject = getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, objectToRegister.getClass(), descriptor, joinedAttributeManager); 3056 3057 if (registeredObject == null) { 3058 registeredObject = cloneAndRegisterObject(objectToRegister, new CacheKey(primaryKey), joinedAttributeManager); 3061 } 3062 } 3063 3064 if (descriptor.hasFetchGroupManager()) { 3067 if (descriptor.getFetchGroupManager().shouldWriteInto(objectToRegister, registeredObject)) { 3069 descriptor.getFetchGroupManager().writePartialIntoClones(objectToRegister, registeredObject, this); 3071 } 3072 } 3073 } finally { 3074 endOperationProfile(SessionProfiler.Register); 3075 } 3076 return registeredObject; 3077 } 3078 3079 3089 public synchronized Object registerNewObject(Object newObject) { 3090 if (newObject == null) { 3091 return null; 3092 } 3093 ClassDescriptor descriptor = getDescriptor(newObject); 3094 if (descriptor == null) { 3095 throw DescriptorException.missingDescriptor(newObject.getClass().toString()); 3096 } 3097 3098 ObjectBuilder builder = descriptor.getObjectBuilder(); 3099 Object implementation = builder.unwrapObject(newObject, this); 3100 3101 this.registerNewObject(implementation, descriptor); 3102 3103 if (implementation == newObject) { 3104 return newObject; 3105 } else { 3106 return builder.wrapObject(implementation, this); 3107 } 3108 } 3109 3110 3122 protected synchronized Object registerNewObject(Object implementation, ClassDescriptor descriptor) { 3123 if (isAfterWriteChangesButBeforeCommit()) { 3124 throw ValidationException.illegalOperationForUnitOfWorkLifecycle(getLifecycle(), "registerNewObject"); 3125 } 3126 if (descriptor.isAggregateDescriptor() || descriptor.isAggregateCollectionDescriptor()) { 3127 throw ValidationException.cannotRegisterAggregateObjectInUnitOfWork(implementation.getClass()); 3128 } 3129 try { 3130 logDebugMessage(implementation, "register_new"); 3132 3133 startOperationProfile(SessionProfiler.Register); 3134 Object registeredObject = checkIfAlreadyRegistered(implementation, descriptor); 3135 if (registeredObject == null) { 3136 if (shouldPerformFullValidation()) { 3138 Vector primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(implementation, this); 3139 Object objectFromCache = getParent().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, implementation.getClass(), descriptor, null); 3140 if (objectFromCache != null) { 3141 throw ValidationException.wrongObjectRegistered(implementation, objectFromCache); 3142 } 3143 } 3144 ObjectBuilder builder = descriptor.getObjectBuilder(); 3145 Object original = builder.buildNewInstance(); 3146 3147 registerNewObjectClone(implementation, original); 3148 Object backupClone = builder.buildNewInstance(); 3149 getCloneMapping().put(implementation, backupClone); 3150 3151 registerNewObjectInIdentityMap(implementation, implementation); 3153 } 3154 } finally { 3155 endOperationProfile(SessionProfiler.Register); 3156 } 3157 3158 return implementation; 3160 } 3161 3162 3171 public synchronized void registerNewObjectForPersist(Object newObject, IdentityHashtable visitedObjects) { 3172 try { 3173 if (newObject == null) { 3174 return; 3175 } 3176 ClassDescriptor descriptor = getDescriptor(newObject); 3177 if ((descriptor == null) || descriptor.isAggregateDescriptor() || descriptor.isAggregateCollectionDescriptor()) { 3178 throw new IllegalArgumentException (ExceptionLocalization.buildMessage("not_an_entity", new Object []{newObject})); 3179 } 3180 3181 startOperationProfile(SessionProfiler.Register); 3182 3183 Object registeredObject = checkIfAlreadyRegistered(newObject, descriptor); 3184 3185 if (registeredObject == null) { 3186 registerNotRegisteredNewObjectForPersist(newObject, descriptor); 3187 } else if (this.isObjectDeleted(newObject)){ 3188 this.undeleteObject(newObject); 3191 } 3192 descriptor.getObjectBuilder().cascadeRegisterNewForCreate(newObject, this, visitedObjects); 3193 } finally { 3194 endOperationProfile(SessionProfiler.Register); 3195 } 3196 } 3197 3198 3204 protected void registerNotRegisteredNewObjectForPersist(Object newObject, ClassDescriptor descriptor) { 3205 newObject.getClass(); 3207 3208 DoesExistQuery existQuery = descriptor.getQueryManager().getDoesExistQuery(); 3209 existQuery = (DoesExistQuery)existQuery.clone(); 3210 existQuery.setObject(newObject); 3211 existQuery.setDescriptor(descriptor); 3212 existQuery.checkCacheForDoesExist(); 3216 if (((Boolean )executeQuery(existQuery)).booleanValue()) { 3217 throw ValidationException.cannotPersistExistingObject(newObject, this); 3218 } 3219 3220 logDebugMessage(newObject, "register_new_for_persist"); 3221 3222 if (descriptor.getEventManager().hasAnyEventListeners()) { 3223 oracle.toplink.essentials.descriptors.DescriptorEvent event = new oracle.toplink.essentials.descriptors.DescriptorEvent(newObject); 3224 event.setEventCode(DescriptorEventManager.PrePersistEvent); 3225 event.setSession(this); 3226 descriptor.getEventManager().executeEvent(event); 3227 } 3228 3229 ObjectBuilder builder = descriptor.getObjectBuilder(); 3230 Object original = builder.buildNewInstance(); 3231 3232 registerNewObjectClone(newObject, original); 3233 Object backupClone = builder.buildNewInstance(); 3234 getCloneMapping().put(newObject, backupClone); 3235 assignSequenceNumber(newObject); 3236 3237 registerNewObjectInIdentityMap(newObject, newObject); 3239 } 3240 3241 3247 protected void registerNewObjectClone(Object clone, Object original) { 3248 registerNewObjectInIdentityMap(clone, original); 3250 3251 getNewObjectsCloneToOriginal().put(clone, original); 3252 getNewObjectsOriginalToClone().put(original, clone); 3253 } 3254 3255 3260 protected void registerNewObjectInIdentityMap(Object clone, Object original) { 3261 Class cls = clone.getClass(); 3264 ClassDescriptor descriptor = getDescriptor(cls); 3265 boolean usesSequences = descriptor.usesSequenceNumbers(); 3266 if (shouldNewObjectsBeCached()) { 3267 Vector key = keyFromObject(clone, descriptor); 3269 boolean containsNull = false; 3270 3271 Object pkElement; 3273 for (int index = 0; index < key.size(); index++) { 3274 pkElement = key.elementAt(index); 3275 if (pkElement == null) { 3276 containsNull = true; 3277 } else if (usesSequences) { 3278 containsNull = getSequencing().shouldOverrideExistingValue(cls, pkElement); 3279 } 3280 } 3281 if (containsNull) { 3282 key = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(original, this); 3283 containsNull = false; 3284 for (int index = 0; index < key.size(); index++) { 3285 pkElement = key.elementAt(index); 3286 if (pkElement == null) { 3287 containsNull = true; 3288 } else if (usesSequences) { 3289 containsNull = getSequencing().shouldOverrideExistingValue(cls, pkElement); 3290 } 3291 } 3292 } 3293 3294 if (!containsNull) { 3296 getIdentityMapAccessorInstance().putInIdentityMap(clone, key, null, 0, descriptor); 3297 } 3298 } 3299 } 3300 3301 3313 public synchronized Object registerObject(Object object) { 3314 if (object == null) { 3315 return null; 3316 } 3317 ClassDescriptor descriptor = getDescriptor(object); 3318 if (descriptor == null) { 3319 throw DescriptorException.missingDescriptor(object.getClass().toString()); 3320 } 3321 if (this.isClassReadOnly(descriptor.getJavaClass(), descriptor)) { 3322 return object; 3323 } 3324 ObjectBuilder builder = descriptor.getObjectBuilder(); 3325 Object implementation = builder.unwrapObject(object, this); 3326 boolean wasWrapped = implementation != object; 3327 Object registeredObject = this.registerObject(implementation, descriptor); 3328 if (wasWrapped) { 3329 return builder.wrapObject(registeredObject, this); 3330 } else { 3331 return registeredObject; 3332 } 3333 } 3334 3335 3354 protected synchronized Object registerObject(Object object, ClassDescriptor descriptor) { 3355 if (this.isClassReadOnly(descriptor.getJavaClass(), descriptor)) { 3356 return object; 3357 } 3358 if (isAfterWriteChangesButBeforeCommit()) { 3359 throw ValidationException.illegalOperationForUnitOfWorkLifecycle(getLifecycle(), "registerObject"); 3360 } 3361 3362 logDebugMessage(object, "register"); 3364 3365 Object registeredObject; 3366 try { 3367 startOperationProfile(SessionProfiler.Register); 3368 3369 registeredObject = internalRegisterObject(object, descriptor); 3370 3371 } finally { 3372 endOperationProfile(SessionProfiler.Register); 3373 } 3374 return registeredObject; 3375 } 3376 3377 3381 public void registerWithTransactionIfRequired() { 3382 if (getParent().hasExternalTransactionController() && ! isSynchronized()) { 3383 boolean hasAlreadyStarted = getParent().wasJTSTransactionInternallyStarted(); 3384 getParent().getExternalTransactionController().registerSynchronizationListener(this, getParent()); 3385 3386 if (!hasAlreadyStarted && getParent().wasJTSTransactionInternallyStarted()) { 3391 this.setWasTransactionBegunPrematurely(true); 3394 } 3395 } 3396 } 3397 3398 3407 public void release() { 3408 log(SessionLog.FINER, SessionLog.TRANSACTION, "release_unit_of_work"); 3409 getEventManager().preReleaseUnitOfWork(); 3410 3411 if (getLifecycle() == CommitTransactionPending) { 3414 if (hasModifications() || wasTransactionBegunPrematurely()) { 3415 rollbackTransaction(false); 3416 setWasTransactionBegunPrematurely(false); 3417 } 3418 } else if (wasTransactionBegunPrematurely() && (!isNestedUnitOfWork())) { 3419 rollbackTransaction(); 3420 setWasTransactionBegunPrematurely(false); 3421 } 3422 if ((getMergeManager() != null) && (getMergeManager().getAcquiredLocks() != null) && (!getMergeManager().getAcquiredLocks().isEmpty())) { 3423 getParent().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(getMergeManager()); 3426 this.setMergeManager(null); 3427 } 3428 setDead(); 3429 getParent().releaseUnitOfWork(this); 3430 getEventManager().postReleaseUnitOfWork(); 3431 } 3432 3433 3440 public void removeAllReadOnlyClasses() throws ValidationException { 3441 if (isNestedUnitOfWork()) { 3442 throw ValidationException.cannotRemoveFromReadOnlyClassesInNestedUnitOfWork(); 3443 } 3444 getReadOnlyClasses().clear(); 3445 } 3446 3447 3452 public void removeForceUpdateToVersionField(Object lockObject) { 3453 getOptimisticReadLockObjects().remove(lockObject); 3454 } 3455 3456 3461 public void removeReadOnlyClass(Class theClass) throws ValidationException { 3462 if (!canChangeReadOnlySet()) { 3463 throw ValidationException.cannotModifyReadOnlyClassesSetAfterUsingUnitOfWork(); 3464 } 3465 if (isNestedUnitOfWork()) { 3466 throw ValidationException.cannotRemoveFromReadOnlyClassesInNestedUnitOfWork(); 3467 } 3468 getReadOnlyClasses().remove(theClass); 3469 3470 } 3471 3472 3476 protected void resetAllCloneCollection() { 3477 this.allClones = null; 3478 } 3479 3480 3491 public void revertAndResume() { 3492 if (isAfterWriteChangesButBeforeCommit()) { 3493 throw ValidationException.illegalOperationForUnitOfWorkLifecycle(getLifecycle(), "revertAndResume"); 3494 } 3495 log(SessionLog.FINER, SessionLog.TRANSACTION, "revert_unit_of_work"); 3496 3497 MergeManager manager = new MergeManager(this); 3498 manager.mergeOriginalIntoWorkingCopy(); 3499 manager.cascadeAllParts(); 3500 for (Enumeration cloneEnum = getCloneMapping().keys(); cloneEnum.hasMoreElements();) { 3501 Object clone = cloneEnum.nextElement(); 3502 3503 manager.mergeChanges(clone, null); 3505 ClassDescriptor descriptor = this.getDescriptor(clone); 3506 3507 descriptor.getObjectChangePolicy().revertChanges(clone, descriptor, this, this.getCloneMapping()); 3509 } 3510 3511 if (hasNewObjects()) { 3513 for (Enumeration cloneEnum = getNewObjectsCloneToOriginal().keys(); 3514 cloneEnum.hasMoreElements();) { 3515 Object clone = cloneEnum.nextElement(); 3516 3517 getCloneMapping().remove(clone); 3519 3520 } 3521 if (this.getUnitOfWorkChangeSet() != null){ 3522 ((UnitOfWorkChangeSet)this.getUnitOfWorkChangeSet()).getNewObjectChangeSets().clear(); 3523 } 3524 } 3525 3526 setNewObjectsCloneToOriginal(null); 3528 setNewObjectsOriginalToClone(null); 3529 resetAllCloneCollection(); 3531 setObjectsDeletedDuringCommit(new IdentityHashtable()); 3533 setDeletedObjects(new IdentityHashtable()); 3534 setRemovedObjects(new IdentityHashtable()); 3535 setUnregisteredNewObjects(new IdentityHashtable()); 3536 log(SessionLog.FINER, SessionLog.TRANSACTION, "resume_unit_of_work"); 3537 } 3538 3539 3548 public Object revertObject(Object clone) { 3549 return revertObject(clone, MergeManager.CASCADE_PRIVATE_PARTS); 3550 } 3551 3552 3557 public Object revertObject(Object clone, int cascadeDepth) { 3558 if (clone == null) { 3559 return null; 3560 } 3561 3562 logDebugMessage(clone, "revert"); 3564 3565 ClassDescriptor descriptor = getDescriptor(clone); 3566 ObjectBuilder builder = descriptor.getObjectBuilder(); 3567 Object implementation = builder.unwrapObject(clone, this); 3568 3569 MergeManager manager = new MergeManager(this); 3570 manager.mergeOriginalIntoWorkingCopy(); 3571 manager.setCascadePolicy(cascadeDepth); 3572 try { 3573 manager.mergeChanges(implementation, null); 3574 } catch (RuntimeException exception) { 3575 return handleException(exception); 3576 } 3577 return clone; 3578 } 3579 3580 3585 public void rollbackTransaction() throws DatabaseException { 3586 incrementProfile(SessionProfiler.UowRollbacks); 3587 getParent().rollbackTransaction(); 3588 } 3589 3590 3604 protected void rollbackTransaction(boolean intendedToCommitTransaction) throws DatabaseException { 3605 if (!intendedToCommitTransaction && getParent().hasExternalTransactionController() && !getParent().wasJTSTransactionInternallyStarted()) { 3606 getParent().getExternalTransactionController().markTransactionForRollback(); 3607 } 3608 rollbackTransaction(); 3609 } 3610 3611 3621 public IdentityHashtable scanForConformingInstances(Expression selectionCriteria, Class referenceClass, AbstractRecord arguments, ObjectLevelReadQuery query) { 3622 InMemoryQueryIndirectionPolicy policy = query.getInMemoryQueryIndirectionPolicy(); 3624 if (!policy.shouldTriggerIndirection()) { 3625 policy = new InMemoryQueryIndirectionPolicy(InMemoryQueryIndirectionPolicy.SHOULD_IGNORE_EXCEPTION_RETURN_NOT_CONFORMED); 3626 } 3627 IdentityHashtable indexedInterimResult = new IdentityHashtable(); 3628 try { 3629 Vector fromCache = null; 3630 if (selectionCriteria != null) { 3631 fromCache = getIdentityMapAccessor().getAllFromIdentityMap(selectionCriteria, referenceClass, arguments, policy); 3635 for (Enumeration fromCacheEnum = fromCache.elements(); 3636 fromCacheEnum.hasMoreElements();) { 3637 Object object = fromCacheEnum.nextElement(); 3638 if (!isObjectDeleted(object)) { 3639 indexedInterimResult.put(object, object); 3640 } 3641 } 3642 } 3643 3644 Vector newObjects = null; 3646 newObjects = getAllFromNewObjects(selectionCriteria, referenceClass, arguments, policy); 3647 for (Enumeration newObjectsEnum = newObjects.elements(); 3648 newObjectsEnum.hasMoreElements();) { 3649 Object object = newObjectsEnum.nextElement(); 3650 if (!isObjectDeleted(object)) { 3651 indexedInterimResult.put(object, object); 3652 } 3653 } 3654 } catch (QueryException exception) { 3655 if (getShouldThrowConformExceptions() == THROW_ALL_CONFORM_EXCEPTIONS) { 3656 throw exception; 3657 } 3658 } 3659 return indexedInterimResult; 3660 } 3661 3662 3667 protected void setAllClonesCollection(IdentityHashtable objects) { 3668 this.allClones = objects; 3669 } 3670 3671 3680 protected void setCloneMapping(IdentityHashtable cloneMapping) { 3681 this.cloneMapping = cloneMapping; 3682 } 3683 3684 3688 public void setDead() { 3689 setLifecycle(Death); 3690 } 3691 3692 3697 protected void setDeletedObjects(IdentityHashtable deletedObjects) { 3698 this.deletedObjects = deletedObjects; 3699 } 3700 3701 3705 protected void setLifecycle(int lifecycle) { 3706 this.lifecycle = lifecycle; 3707 } 3708 3709 3714 public void setMergeManager(MergeManager mergeManager) { 3715 this.lastUsedMergeManager = mergeManager; 3716 } 3717 3718 3723 protected void setNewObjectsCloneToOriginal(IdentityHashtable newObjects) { 3724 this.newObjectsCloneToOriginal = newObjects; 3725 } 3726 3727 3732 protected void setNewObjectsOriginalToClone(IdentityHashtable newObjects) { 3733 this.newObjectsOriginalToClone = newObjects; 3734 } 3735 3736 3740 public void setObjectsDeletedDuringCommit(IdentityHashtable deletedObjects) { 3741 objectsDeletedDuringCommit = deletedObjects; 3742 } 3743 3744 3749 public void setParent(AbstractSession parent) { 3750 this.parent = parent; 3751 } 3752 3753 3757 public void setPendingMerge() { 3758 setLifecycle(MergePending); 3759 } 3760 3761 3767 public void setReadOnlyClasses(Vector classes) { 3768 this.readOnlyClasses = new Hashtable(classes.size() + 10); 3769 for (Enumeration enumtr = classes.elements(); enumtr.hasMoreElements();) { 3770 Class theClass = (Class )enumtr.nextElement(); 3771 addReadOnlyClass(theClass); 3772 } 3773 } 3774 3775 3780 protected void setRemovedObjects(IdentityHashtable removedObjects) { 3781 this.removedObjects = removedObjects; 3782 } 3783 3784 3789 public void setResumeUnitOfWorkOnTransactionCompletion(boolean resumeUnitOfWork){ 3790 this.resumeOnTransactionCompletion = resumeUnitOfWork; 3791 } 3792 3793 3798 public void setShouldCascadeCloneToJoinedRelationship(boolean shouldCascadeCloneToJoinedRelationship) { 3799 this.shouldCascadeCloneToJoinedRelationship = shouldCascadeCloneToJoinedRelationship; 3800 } 3801 3802 3812 public void setShouldNewObjectsBeCached(boolean shouldNewObjectsBeCached) { 3813 this.shouldNewObjectsBeCached = shouldNewObjectsBeCached; 3814 } 3815 3816 3821 public void setShouldPerformDeletesFirst(boolean shouldPerformDeletesFirst) { 3822 this.shouldPerformDeletesFirst = shouldPerformDeletesFirst; 3823 } 3824 3825 3833 public void setShouldThrowConformExceptions(int shouldThrowExceptions) { 3834 this.shouldThrowConformExceptions = shouldThrowExceptions; 3835 } 3836 3837 3841 public static void setSmartMerge(boolean option) { 3842 SmartMerge = option; 3843 } 3844 3845 3849 public void setSynchronized(boolean synched) { 3850 isSynchronized = synched; 3851 } 3852 3853 3857 public void setUnitOfWorkChangeSet(UnitOfWorkChangeSet unitOfWorkChangeSet) { 3858 this.unitOfWorkChangeSet = unitOfWorkChangeSet; 3859 } 3860 3861 3866 protected void setUnregisteredExistingObjects(oracle.toplink.essentials.internal.helper.IdentityHashtable newUnregisteredExistingObjects) { 3867 unregisteredExistingObjects = newUnregisteredExistingObjects; 3868 } 3869 3870 3873 protected void setUnregisteredNewObjects(IdentityHashtable newObjects) { 3874 unregisteredNewObjects = newObjects; 3875 } 3876 3877 3887 public void setValidationLevel(int validationLevel) { 3888 this.validationLevel = validationLevel; 3889 } 3890 3891 3896 public void setWasTransactionBegunPrematurely(boolean wasTransactionBegunPrematurely) { 3897 if (isNestedUnitOfWork()) { 3898 ((UnitOfWorkImpl)getParent()).setWasTransactionBegunPrematurely(wasTransactionBegunPrematurely); 3899 } 3900 this.wasTransactionBegunPrematurely = wasTransactionBegunPrematurely; 3901 } 3902 3903 3917 public Object shallowMergeClone(Object rmiClone) { 3918 return mergeClone(rmiClone, MergeManager.NO_CASCADE); 3919 } 3920 3921 3930 public Object shallowRevertObject(Object clone) { 3931 return revertObject(clone, MergeManager.NO_CASCADE); 3932 } 3933 3934 3941 public void shallowUnregisterObject(Object clone) { 3942 unregisterObject(clone, DescriptorIterator.NoCascading); 3943 } 3944 3945 3950 public boolean shouldCascadeCloneToJoinedRelationship() { 3951 return shouldCascadeCloneToJoinedRelationship; 3952 } 3953 3954 3964 public boolean shouldNewObjectsBeCached() { 3965 return shouldNewObjectsBeCached; 3966 } 3967 3968 3974 public boolean shouldPerformDeletesFirst() { 3975 return shouldPerformDeletesFirst; 3976 } 3977 3978 3988 public boolean shouldPerformFullValidation() { 3989 return getValidationLevel() == Full; 3990 } 3991 3992 4002 public boolean shouldPerformNoValidation() { 4003 return getValidationLevel() == None; 4004 } 4005 4006 4016 public boolean shouldPerformPartialValidation() { 4017 return getValidationLevel() == Partial; 4018 } 4019 4020 4025 public boolean shouldResumeUnitOfWorkOnTransactionCompletion(){ 4026 return this.resumeOnTransactionCompletion; 4027 } 4028 4029 4034 public void storeModifyAllQuery(DatabaseQuery query) { 4035 if (modifyAllQueries == null) { 4036 modifyAllQueries = new ArrayList(); 4037 } 4038 4039 modifyAllQueries.add(query); 4040 } 4041 4042 4046 public void storeDeferredModifyAllQuery(DatabaseQuery query, AbstractRecord translationRow) { 4047 if (deferredModifyAllQueries == null) { 4048 deferredModifyAllQueries = new ArrayList(); 4049 } 4050 deferredModifyAllQueries.add(new Object []{query, translationRow}); 4051 } 4052 4053 4058 public void synchronizeAndResume() { 4059 getPessimisticLockedObjects().clear(); 4061 getProperties().remove(LOCK_QUERIES_PROPERTY); 4062 4063 IdentityHashtable newCloneMapping = new IdentityHashtable(1 + getCloneMapping().size()); 4065 4066 for (Enumeration cloneEnum = getCloneMapping().keys(); cloneEnum.hasMoreElements();) { 4067 Object clone = cloneEnum.nextElement(); 4068 4069 if ((!isObjectDeleted(clone)) && (!getRemovedObjects().containsKey(clone))) { 4071 ClassDescriptor descriptor = getDescriptor(clone); 4072 ObjectBuilder builder = descriptor.getObjectBuilder(); 4073 4074 descriptor.getObjectChangePolicy().revertChanges(clone, descriptor, this, newCloneMapping); 4077 } 4078 } 4079 setCloneMapping(newCloneMapping); 4080 4081 if (hasObjectsDeletedDuringCommit()) { 4082 for (Enumeration removedObjects = getObjectsDeletedDuringCommit().keys(); 4083 removedObjects.hasMoreElements();) { 4084 Object removedObject = removedObjects.nextElement(); 4085 getIdentityMapAccessor().removeFromIdentityMap((Vector)getObjectsDeletedDuringCommit().get(removedObject), removedObject.getClass()); 4086 } 4087 } 4088 4089 if (!isNestedUnitOfWork()) { 4092 if (hasNewObjects()) { 4094 for (Enumeration newClones = getNewObjectsCloneToOriginal().keys(); newClones.hasMoreElements();) { 4095 Object newClone = newClones.nextElement(); 4096 getCloneToOriginals().put(newClone, getNewObjectsCloneToOriginal().get(newClone)); 4097 } 4098 } 4099 setNewObjectsCloneToOriginal(null); 4100 setNewObjectsOriginalToClone(null); 4101 } 4102 4103 setUnitOfWorkChangeSet(null); 4105 4106 resetAllCloneCollection(); 4108 setObjectsDeletedDuringCommit(new IdentityHashtable()); 4110 setDeletedObjects(new IdentityHashtable()); 4111 setRemovedObjects(new IdentityHashtable()); 4112 setUnregisteredNewObjects(new IdentityHashtable()); 4113 this.lifecycle = Birth; 4115 this.isSynchronized = false; 4116 } 4117 4118 4123 protected void undeleteObject(Object object){ 4124 getDeletedObjects().remove(object); 4125 if (getParent().isUnitOfWork()) { 4126 ((UnitOfWorkImpl)getParent()).undeleteObject(object); 4127 } 4128 } 4129 4130 4137 public void unregisterObject(Object clone) { 4138 unregisterObject(clone, DescriptorIterator.CascadePrivateParts); 4139 } 4140 4141 4147 public void unregisterObject(Object clone, int cascadeDepth) { 4148 if (clone == null) { 4150 return; 4151 } 4152 4153 logDebugMessage(clone, "unregister"); 4155 Object implementation = getDescriptor(clone).getObjectBuilder().unwrapObject(clone, this); 4156 4157 DescriptorIterator iterator = new DescriptorIterator() { 4159 public void iterate(Object object) { 4160 if (isClassReadOnly(object.getClass(), getCurrentDescriptor())) { 4161 setShouldBreak(true); 4162 return; 4163 } 4164 4165 Vector primaryKey = getCurrentDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(object, UnitOfWorkImpl.this); 4167 4168 getIdentityMapAccessorInstance().removeFromIdentityMap(primaryKey, object.getClass(), getCurrentDescriptor()); 4170 getCloneMapping().remove(object); 4171 4172 if (hasNewObjects()) { 4175 Object original = getNewObjectsCloneToOriginal().remove(object); 4176 if (original != null) { 4177 getNewObjectsOriginalToClone().remove(original); 4178 } 4179 } 4180 } 4181 }; 4182 4183 iterator.setSession(this); 4184 iterator.setCascadeDepth(cascadeDepth); 4185 iterator.startIterationOn(implementation); 4186 } 4187 4188 4192 public void updateChangeTrackersIfRequired(Object objectToWrite, ObjectChangeSet changeSetToWrite, UnitOfWorkImpl uow, ClassDescriptor descriptor) { 4193 } 4195 4196 4204 public void validateObjectSpace() { 4205 log(SessionLog.FINER, SessionLog.TRANSACTION, "validate_object_space"); 4206 DescriptorIterator iterator = new DescriptorIterator() { 4208 public void iterate(Object object) { 4209 try { 4210 if (isClassReadOnly(object.getClass(), getCurrentDescriptor())) { 4211 setShouldBreak(true); 4212 return; 4213 } else { 4214 getBackupClone(object); 4215 } 4216 } catch (TopLinkException exception) { 4217 log(SessionLog.FINEST, SessionLog.TRANSACTION, "stack_of_visited_objects_that_refer_to_the_corrupt_object", getVisitedStack()); 4218 log(SessionLog.FINER, SessionLog.TRANSACTION, "corrupt_object_referenced_through_mapping", getCurrentMapping()); 4219 throw exception; 4220 } 4221 } 4222 }; 4223 4224 iterator.setSession(this); 4225 for (Enumeration clonesEnum = getCloneMapping().keys(); clonesEnum.hasMoreElements();) { 4226 iterator.startIterationOn(clonesEnum.nextElement()); 4227 } 4228 } 4229 4230 4235 4236 public boolean wasTransactionBegunPrematurely() { 4239 if (isNestedUnitOfWork()) { 4240 return ((UnitOfWorkImpl)getParent()).wasTransactionBegunPrematurely(); 4241 } 4242 return wasTransactionBegunPrematurely; 4243 } 4244 4245 4263 public void writeChanges() { 4264 if (!isActive()) { 4265 throw ValidationException.inActiveUnitOfWork("writeChanges"); 4266 } 4267 if (isAfterWriteChangesButBeforeCommit()) { 4268 throw ValidationException.cannotWriteChangesTwice(); 4269 } 4270 if (isNestedUnitOfWork()) { 4271 throw ValidationException.writeChangesOnNestedUnitOfWork(); 4272 } 4273 log(SessionLog.FINER, SessionLog.TRANSACTION, "begin_unit_of_work_commit"); 4274 getEventManager().preCommitUnitOfWork(); 4275 setLifecycle(CommitPending); 4276 try { 4277 commitToDatabaseWithChangeSet(false); 4278 } catch (RuntimeException e) { 4279 setLifecycle(WriteChangesFailed); 4280 throw e; 4281 } 4282 setLifecycle(CommitTransactionPending); 4283 } 4284 4285 4291 public void writesCompleted() { 4292 getParent().writesCompleted(); 4293 } 4294 4295 4298 private void logDebugMessage(Object object, String debugMessage) { 4299 log(SessionLog.FINEST, SessionLog.TRANSACTION, debugMessage, object); 4300 } 4301 4302 4307 public Object getWorkingCopyFromUnitOfWorkIdentityMap(Object object, Vector primaryKey) { 4308 ClassDescriptor descriptor = getDescriptor(object); 4310 if (descriptor == null) { 4311 throw DescriptorException.missingDescriptor(object.getClass().toString()); 4312 } 4313 4314 if (descriptor.isAggregateDescriptor() || descriptor.isAggregateCollectionDescriptor()) { 4316 throw ValidationException.cannotRegisterAggregateObjectInUnitOfWork(object.getClass()); 4317 } 4318 4319 Object registeredObject = getCloneMapping().get(object); 4321 if (registeredObject != null) { 4322 return object; 4323 } 4324 4325 Object objectFromUOWCache = getIdentityMapAccessorInstance().getIdentityMapManager().getFromIdentityMap(primaryKey, object.getClass(), descriptor); 4327 if (objectFromUOWCache != null) { 4328 return objectFromUOWCache; 4330 } 4331 4332 return null; 4334 } 4335 4336 4339 public IdentityHashtable getPessimisticLockedObjects() { 4340 if (pessimisticLockedObjects == null) { 4341 pessimisticLockedObjects = new IdentityHashtable(); 4343 } 4344 return pessimisticLockedObjects; 4345 } 4346 4347 4350 public void addPessimisticLockedClone(Object clone) { 4351 log(SessionLog.FINEST, SessionLog.TRANSACTION, "tracking_pl_object", clone, new Integer (this.hashCode())); 4352 getPessimisticLockedObjects().put(clone, clone); 4353 } 4354 4355 4358 public boolean isPessimisticLocked(Object clone) { 4359 return getPessimisticLockedObjects().containsKey(clone); 4360 } 4361 4362 4368 public void setWasNonObjectLevelModifyQueryExecuted(boolean wasNonObjectLevelModifyQueryExecuted) { 4369 this.wasNonObjectLevelModifyQueryExecuted = wasNonObjectLevelModifyQueryExecuted; 4370 } 4371 4372 4376 public boolean wasNonObjectLevelModifyQueryExecuted() { 4377 return wasNonObjectLevelModifyQueryExecuted; 4378 } 4379 4380 4386 public boolean shouldReadFromDB() { 4387 return wasNonObjectLevelModifyQueryExecuted(); 4388 } 4389} 4390 | Popular Tags |