|
Lines 29-35
Link Here
|
| 29 |
import org.eclipse.persistence.internal.descriptors.*; |
29 |
import org.eclipse.persistence.internal.descriptors.*; |
| 30 |
import org.eclipse.persistence.internal.expressions.*; |
30 |
import org.eclipse.persistence.internal.expressions.*; |
| 31 |
import org.eclipse.persistence.internal.helper.*; |
31 |
import org.eclipse.persistence.internal.helper.*; |
| 32 |
import org.eclipse.persistence.internal.identitymaps.*; |
|
|
| 33 |
import org.eclipse.persistence.internal.indirection.*; |
32 |
import org.eclipse.persistence.internal.indirection.*; |
| 34 |
import org.eclipse.persistence.internal.queries.*; |
33 |
import org.eclipse.persistence.internal.queries.*; |
| 35 |
import org.eclipse.persistence.internal.sessions.remote.*; |
34 |
import org.eclipse.persistence.internal.sessions.remote.*; |
|
Lines 533-539
Link Here
|
| 533 |
containerPolicy.propogatePostUpdate(query, addedChangeSet.getNewKey()); |
532 |
containerPolicy.propogatePostUpdate(query, addedChangeSet.getNewKey()); |
| 534 |
} |
533 |
} |
| 535 |
} |
534 |
} |
| 536 |
if(listOrderField != null) { |
535 |
if (listOrderField != null) { |
| 537 |
List previousList = (List)previousObjects; |
536 |
List previousList = (List)previousObjects; |
| 538 |
int previousSize = previousList.size(); |
537 |
int previousSize = previousList.size(); |
| 539 |
List currentList = (List)currentObjects; |
538 |
List currentList = (List)currentObjects; |
|
Lines 562-568
Link Here
|
| 562 |
} |
561 |
} |
| 563 |
} |
562 |
} |
| 564 |
} else { |
563 |
} else { |
| 565 |
for(int i=0; i < previousSize; i++) { |
564 |
for (int i=0; i < previousSize; i++) { |
| 566 |
// TODO: should we check for previousObject != null? |
565 |
// TODO: should we check for previousObject != null? |
| 567 |
Object prevObject = previousList.get(i); |
566 |
Object prevObject = previousList.get(i); |
| 568 |
Object currentObject = null; |
567 |
Object currentObject = null; |
|
Lines 578-584
Link Here
|
| 578 |
} |
577 |
} |
| 579 |
} |
578 |
} |
| 580 |
} |
579 |
} |
| 581 |
if(shouldRepairOrder) { |
580 |
if (shouldRepairOrder) { |
| 582 |
((IndirectList)currentList).setIsListOrderBrokenInDb(false); |
581 |
((IndirectList)currentList).setIsListOrderBrokenInDb(false); |
| 583 |
record.setOrderHasBeenRepaired(true); |
582 |
record.setOrderHasBeenRepaired(true); |
| 584 |
} |
583 |
} |
|
Lines 587-603
Link Here
|
| 587 |
return; |
586 |
return; |
| 588 |
} |
587 |
} |
| 589 |
|
588 |
|
| 590 |
if(this.listOrderField != null && this.isAggregateCollectionMapping()) { |
589 |
if (this.listOrderField != null && this.isAggregateCollectionMapping()) { |
| 591 |
this.compareListsAndWrite((List)previousObjects, (List)currentObjects, query); |
590 |
this.compareListsAndWrite((List)previousObjects, (List)currentObjects, query); |
| 592 |
return; |
591 |
return; |
| 593 |
} |
592 |
} |
| 594 |
|
593 |
|
| 595 |
ContainerPolicy cp = this.containerPolicy; |
594 |
ContainerPolicy cp = this.containerPolicy; |
| 596 |
|
595 |
|
| 597 |
Hashtable previousObjectsByKey = new Hashtable(cp.sizeFor(previousObjects) + 2); // Read from db or from backup in uow. |
596 |
Map previousObjectsByKey = new HashMap(cp.sizeFor(previousObjects)); // Read from db or from backup in uow. |
| 598 |
Hashtable currentObjectsByKey = new Hashtable(cp.sizeFor(currentObjects) + 2); // Current value of object's attribute (clone in uow). |
597 |
Map currentObjectsByKey = new HashMap(cp.sizeFor(currentObjects)); // Current value of object's attribute (clone in uow). |
| 599 |
|
598 |
|
| 600 |
Map cacheKeysOfCurrentObjects = new IdentityHashMap(cp.sizeFor(currentObjects) + 1); |
599 |
Map keysOfCurrentObjects = new IdentityHashMap(cp.sizeFor(currentObjects) + 1); |
| 601 |
|
600 |
|
| 602 |
// First index the current objects by their primary key. |
601 |
// First index the current objects by their primary key. |
| 603 |
for (Object currentObjectsIter = cp.iteratorFor(currentObjects); |
602 |
for (Object currentObjectsIter = cp.iteratorFor(currentObjects); |
|
Lines 605-613
Link Here
|
| 605 |
Object currentObject = cp.next(currentObjectsIter, query.getSession()); |
604 |
Object currentObject = cp.next(currentObjectsIter, query.getSession()); |
| 606 |
try { |
605 |
try { |
| 607 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(currentObject, query.getSession()); |
606 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(currentObject, query.getSession()); |
| 608 |
CacheKey key = new CacheKey(primaryKey); |
607 |
currentObjectsByKey.put(primaryKey, currentObject); |
| 609 |
currentObjectsByKey.put(key, currentObject); |
608 |
keysOfCurrentObjects.put(currentObject, primaryKey); |
| 610 |
cacheKeysOfCurrentObjects.put(currentObject, key); |
|
|
| 611 |
} catch (NullPointerException e) { |
609 |
} catch (NullPointerException e) { |
| 612 |
// For CR#2646 quietly discard nulls added to a collection mapping. |
610 |
// For CR#2646 quietly discard nulls added to a collection mapping. |
| 613 |
// This try-catch is essentially a null check on currentObject, for |
611 |
// This try-catch is essentially a null check on currentObject, for |
|
Lines 626-636
Link Here
|
| 626 |
Map mapKeyFields = containerPolicy.getKeyMappingDataForWriteQuery(wrappedObject, query.getSession()); |
624 |
Map mapKeyFields = containerPolicy.getKeyMappingDataForWriteQuery(wrappedObject, query.getSession()); |
| 627 |
Object previousObject = containerPolicy.unwrapIteratorResult(wrappedObject); |
625 |
Object previousObject = containerPolicy.unwrapIteratorResult(wrappedObject); |
| 628 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(previousObject, query.getSession()); |
626 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(previousObject, query.getSession()); |
| 629 |
CacheKey key = new CacheKey(primaryKey); |
627 |
previousObjectsByKey.put(primaryKey, previousObject); |
| 630 |
previousObjectsByKey.put(key, previousObject); |
|
|
| 631 |
// Delete must occur first, in case object with same pk is removed and added, |
628 |
// Delete must occur first, in case object with same pk is removed and added, |
| 632 |
// (technically should not happen, but same applies to unique constraints) |
629 |
// (technically should not happen, but same applies to unique constraints) |
| 633 |
if (!currentObjectsByKey.containsKey(key)) { |
630 |
if (!currentObjectsByKey.containsKey(primaryKey)) { |
| 634 |
objectRemovedDuringUpdate(query, wrappedObject, mapKeyFields); |
631 |
objectRemovedDuringUpdate(query, wrappedObject, mapKeyFields); |
| 635 |
cp.propogatePostUpdate(query, wrappedObject); |
632 |
cp.propogatePostUpdate(query, wrappedObject); |
| 636 |
} |
633 |
} |
|
Lines 642-654
Link Here
|
| 642 |
Object currentObject = containerPolicy.unwrapIteratorResult(wrappedObject); |
639 |
Object currentObject = containerPolicy.unwrapIteratorResult(wrappedObject); |
| 643 |
try { |
640 |
try { |
| 644 |
Map mapKeyFields = containerPolicy.getKeyMappingDataForWriteQuery(wrappedObject, query.getSession()); |
641 |
Map mapKeyFields = containerPolicy.getKeyMappingDataForWriteQuery(wrappedObject, query.getSession()); |
| 645 |
CacheKey cacheKey = (CacheKey)cacheKeysOfCurrentObjects.get(currentObject); |
642 |
Object primaryKey = keysOfCurrentObjects.get(currentObject); |
| 646 |
|
643 |
|
| 647 |
if (!(previousObjectsByKey.containsKey(cacheKey))) { |
644 |
if (!(previousObjectsByKey.containsKey(primaryKey))) { |
| 648 |
objectAddedDuringUpdate(query, currentObject, null, mapKeyFields); |
645 |
objectAddedDuringUpdate(query, currentObject, null, mapKeyFields); |
| 649 |
cp.propogatePostUpdate(query, wrappedObject); |
646 |
cp.propogatePostUpdate(query, wrappedObject); |
| 650 |
} else { |
647 |
} else { |
| 651 |
objectUnchangedDuringUpdate(query, currentObject, previousObjectsByKey, cacheKey); |
648 |
objectUnchangedDuringUpdate(query, currentObject, previousObjectsByKey, primaryKey); |
| 652 |
} |
649 |
} |
| 653 |
} catch (NullPointerException e) { |
650 |
} catch (NullPointerException e) { |
| 654 |
// For CR#2646 skip currentObject if it is null. |
651 |
// For CR#2646 skip currentObject if it is null. |
|
Lines 685-703
Link Here
|
| 685 |
Object firstIter = cp.iteratorFor(firstCollection); |
682 |
Object firstIter = cp.iteratorFor(firstCollection); |
| 686 |
Object secondIter = cp.iteratorFor(secondCollection); |
683 |
Object secondIter = cp.iteratorFor(secondCollection); |
| 687 |
|
684 |
|
| 688 |
Vector keyValue = new Vector(); |
685 |
Set keyValue = new HashSet(); |
| 689 |
|
686 |
|
| 690 |
while (cp.hasNext(secondIter)) { |
687 |
while (cp.hasNext(secondIter)) { |
| 691 |
Object secondObject = cp.next(secondIter, session); |
688 |
Object secondObject = cp.next(secondIter, session); |
| 692 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(secondObject, session); |
689 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(secondObject, session); |
| 693 |
keyValue.add(new CacheKey(primaryKey)); |
690 |
keyValue.add(primaryKey); |
| 694 |
} |
691 |
} |
| 695 |
|
692 |
|
| 696 |
while (cp.hasNext(firstIter)) { |
693 |
while (cp.hasNext(firstIter)) { |
| 697 |
Object firstObject = cp.next(firstIter, session); |
694 |
Object firstObject = cp.next(firstIter, session); |
| 698 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(firstObject, session); |
695 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(firstObject, session); |
| 699 |
|
696 |
|
| 700 |
if (!keyValue.contains(new CacheKey(primaryKey))) { |
697 |
if (!keyValue.contains(primaryKey)) { |
| 701 |
return false; |
698 |
return false; |
| 702 |
} |
699 |
} |
| 703 |
} |
700 |
} |
|
Lines 720-742
Link Here
|
| 720 |
Object firstIter = cp.iteratorFor(firstCollection); |
717 |
Object firstIter = cp.iteratorFor(firstCollection); |
| 721 |
Object secondIter = cp.iteratorFor(secondCollection); |
718 |
Object secondIter = cp.iteratorFor(secondCollection); |
| 722 |
|
719 |
|
| 723 |
Hashtable keyValueToObject = new Hashtable(cp.sizeFor(firstCollection) + 2); |
720 |
Map keyValueToObject = new HashMap(cp.sizeFor(firstCollection)); |
| 724 |
CacheKey cacheKey; |
|
|
| 725 |
|
721 |
|
| 726 |
while (cp.hasNext(secondIter)) { |
722 |
while (cp.hasNext(secondIter)) { |
| 727 |
Object secondObject = cp.next(secondIter, session); |
723 |
Object secondObject = cp.next(secondIter, session); |
| 728 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(secondObject, session); |
724 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(secondObject, session); |
| 729 |
keyValueToObject.put(new CacheKey(primaryKey), secondObject); |
725 |
keyValueToObject.put(primaryKey, secondObject); |
| 730 |
} |
726 |
} |
| 731 |
|
727 |
|
| 732 |
while (cp.hasNext(firstIter)) { |
728 |
while (cp.hasNext(firstIter)) { |
| 733 |
Object firstObject = cp.next(firstIter, session); |
729 |
Object firstObject = cp.next(firstIter, session); |
| 734 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(firstObject, session); |
730 |
Object primaryKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(firstObject, session); |
| 735 |
cacheKey = new CacheKey(primaryKey); |
731 |
|
|
|
732 |
if (keyValueToObject.containsKey(primaryKey)) { |
| 733 |
Object object = keyValueToObject.get(primaryKey); |
| 736 |
|
734 |
|
| 737 |
if (keyValueToObject.containsKey(cacheKey)) { |
|
|
| 738 |
Object object = keyValueToObject.get(cacheKey); |
| 739 |
|
| 740 |
if (!session.compareObjects(firstObject, object)) { |
735 |
if (!session.compareObjects(firstObject, object)) { |
| 741 |
return false; |
736 |
return false; |
| 742 |
} |
737 |
} |
|
Lines 766-774
Link Here
|
| 766 |
return false; |
761 |
return false; |
| 767 |
} |
762 |
} |
| 768 |
} else { |
763 |
} else { |
| 769 |
CacheKey firstKey = new CacheKey(getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(firstObject, session)); |
764 |
Object firstKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(firstObject, session); |
| 770 |
CacheKey secondKey = new CacheKey(getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(secondObject, session)); |
765 |
Object secondKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(secondObject, session); |
| 771 |
if(!firstKey.equals(secondKey)) { |
766 |
if (!firstKey.equals(secondKey)) { |
| 772 |
return false; |
767 |
return false; |
| 773 |
} |
768 |
} |
| 774 |
} |
769 |
} |
|
Lines 794-800
Link Here
|
| 794 |
*/ |
789 |
*/ |
| 795 |
public Object extractResultFromBatchQuery(DatabaseQuery query, AbstractRecord databaseRow, AbstractSession session, AbstractRecord argumentRow) { |
790 |
public Object extractResultFromBatchQuery(DatabaseQuery query, AbstractRecord databaseRow, AbstractSession session, AbstractRecord argumentRow) { |
| 796 |
//this can be null, because either one exists in the query or it will be created |
791 |
//this can be null, because either one exists in the query or it will be created |
| 797 |
Hashtable referenceObjectsByKey = null; |
792 |
Map<Object, Object> referenceObjectsByKey = null; |
| 798 |
synchronized (query) { |
793 |
synchronized (query) { |
| 799 |
referenceObjectsByKey = getBatchReadObjects(query, session); |
794 |
referenceObjectsByKey = getBatchReadObjects(query, session); |
| 800 |
if (referenceObjectsByKey == null) { |
795 |
if (referenceObjectsByKey == null) { |
|
Lines 802-818
Link Here
|
| 802 |
ComplexQueryResult complexResult = (ComplexQueryResult)session.executeQuery(batchQuery, argumentRow); |
797 |
ComplexQueryResult complexResult = (ComplexQueryResult)session.executeQuery(batchQuery, argumentRow); |
| 803 |
Object results = complexResult.getResult(); |
798 |
Object results = complexResult.getResult(); |
| 804 |
referenceObjectsByKey = new Hashtable(); |
799 |
referenceObjectsByKey = new Hashtable(); |
| 805 |
Enumeration rowsEnum = ((Vector)complexResult.getData()).elements(); |
800 |
Iterator<AbstractRecord> rowsIterator = ((List<AbstractRecord>)complexResult.getData()).iterator(); |
| 806 |
ContainerPolicy queryContainerPolicy = batchQuery.getContainerPolicy(); |
801 |
ContainerPolicy queryContainerPolicy = batchQuery.getContainerPolicy(); |
| 807 |
if(this.containerPolicy.shouldAddAll()) { |
802 |
if (this.containerPolicy.shouldAddAll()) { |
| 808 |
HashMap<CacheKey, List[]> referenceObjectsAndRowsByKey = new HashMap(); |
803 |
Map<Object, List[]> referenceObjectsAndRowsByKey = new HashMap(); |
| 809 |
for (Object elementsIterator = queryContainerPolicy.iteratorFor(results); queryContainerPolicy.hasNext(elementsIterator);) { |
804 |
for (Object elementsIterator = queryContainerPolicy.iteratorFor(results); queryContainerPolicy.hasNext(elementsIterator);) { |
| 810 |
Object eachReferenceObject = queryContainerPolicy.next(elementsIterator, session); |
805 |
Object eachReferenceObject = queryContainerPolicy.next(elementsIterator, session); |
| 811 |
AbstractRecord row = (AbstractRecord)rowsEnum.nextElement(); |
806 |
AbstractRecord row = rowsIterator.next(); |
| 812 |
CacheKey eachReferenceKey = new CacheKey(extractKeyFromTargetRow(row, session)); |
807 |
Object eachReferenceKey = extractKeyFromTargetRow(row, session); |
| 813 |
|
|
|
| 814 |
List[] objectsAndRows = referenceObjectsAndRowsByKey.get(eachReferenceKey); |
808 |
List[] objectsAndRows = referenceObjectsAndRowsByKey.get(eachReferenceKey); |
| 815 |
if(objectsAndRows == null) { |
809 |
if (objectsAndRows == null) { |
| 816 |
objectsAndRows = new List[]{new ArrayList(), new ArrayList()}; |
810 |
objectsAndRows = new List[]{new ArrayList(), new ArrayList()}; |
| 817 |
referenceObjectsAndRowsByKey.put(eachReferenceKey, objectsAndRows); |
811 |
referenceObjectsAndRowsByKey.put(eachReferenceKey, objectsAndRows); |
| 818 |
} |
812 |
} |
|
Lines 820-829
Link Here
|
| 820 |
objectsAndRows[1].add(row); |
814 |
objectsAndRows[1].add(row); |
| 821 |
} |
815 |
} |
| 822 |
|
816 |
|
| 823 |
Iterator<Map.Entry<CacheKey, List[]>> it = referenceObjectsAndRowsByKey.entrySet().iterator(); |
817 |
Iterator<Map.Entry<Object, List[]>> it = referenceObjectsAndRowsByKey.entrySet().iterator(); |
| 824 |
while(it.hasNext()) { |
818 |
while (it.hasNext()) { |
| 825 |
Map.Entry<CacheKey, List[]> entry = it.next(); |
819 |
Map.Entry<Object, List[]> entry = it.next(); |
| 826 |
CacheKey eachReferenceKey = entry.getKey(); |
820 |
Object eachReferenceKey = entry.getKey(); |
| 827 |
List objects = entry.getValue()[0]; |
821 |
List objects = entry.getValue()[0]; |
| 828 |
List<AbstractRecord> rows = entry.getValue()[1]; |
822 |
List<AbstractRecord> rows = entry.getValue()[1]; |
| 829 |
Object container = this.containerPolicy.containerInstance(objects.size()); |
823 |
Object container = this.containerPolicy.containerInstance(objects.size()); |
|
Lines 833-840
Link Here
|
| 833 |
} else { |
827 |
} else { |
| 834 |
for (Object elementsIterator = queryContainerPolicy.iteratorFor(results); queryContainerPolicy.hasNext(elementsIterator);) { |
828 |
for (Object elementsIterator = queryContainerPolicy.iteratorFor(results); queryContainerPolicy.hasNext(elementsIterator);) { |
| 835 |
Object eachReferenceObject = queryContainerPolicy.next(elementsIterator, session); |
829 |
Object eachReferenceObject = queryContainerPolicy.next(elementsIterator, session); |
| 836 |
AbstractRecord row = (AbstractRecord)rowsEnum.nextElement(); |
830 |
AbstractRecord row = rowsIterator.next(); |
| 837 |
CacheKey eachReferenceKey = new CacheKey(extractKeyFromTargetRow(row, session)); |
831 |
Object eachReferenceKey = extractKeyFromTargetRow(row, session); |
| 838 |
|
832 |
|
| 839 |
Object container = referenceObjectsByKey.get(eachReferenceKey); |
833 |
Object container = referenceObjectsByKey.get(eachReferenceKey); |
| 840 |
if (container == null) { |
834 |
if (container == null) { |
|
Lines 848-854
Link Here
|
| 848 |
query.setSession(null); |
842 |
query.setSession(null); |
| 849 |
} |
843 |
} |
| 850 |
} |
844 |
} |
| 851 |
Object result = referenceObjectsByKey.get(new CacheKey(extractPrimaryKeyFromRow(databaseRow, session))); |
845 |
Object result = referenceObjectsByKey.get(extractPrimaryKeyFromRow(databaseRow, session)); |
| 852 |
|
846 |
|
| 853 |
// The source object might not have any target objects |
847 |
// The source object might not have any target objects |
| 854 |
if (result == null) { |
848 |
if (result == null) { |
|
Lines 868-875
Link Here
|
| 868 |
* The method should be overridden by classes that use batch reading: |
862 |
* The method should be overridden by classes that use batch reading: |
| 869 |
* for those classes extractResultFromBatchQuery method is called. |
863 |
* for those classes extractResultFromBatchQuery method is called. |
| 870 |
*/ |
864 |
*/ |
| 871 |
protected Vector extractKeyFromTargetRow(AbstractRecord row, AbstractSession session) { |
865 |
protected Object extractKeyFromTargetRow(AbstractRecord row, AbstractSession session) { |
| 872 |
return new Vector(0); |
866 |
return null; |
| 873 |
} |
867 |
} |
| 874 |
|
868 |
|
| 875 |
/** |
869 |
/** |
|
Lines 882-889
Link Here
|
| 882 |
* The method should be overridden by classes that use batch reading: |
876 |
* The method should be overridden by classes that use batch reading: |
| 883 |
* for those classes extractResultFromBatchQuery method is called. |
877 |
* for those classes extractResultFromBatchQuery method is called. |
| 884 |
*/ |
878 |
*/ |
| 885 |
protected Vector extractPrimaryKeyFromRow(AbstractRecord row, AbstractSession session) { |
879 |
protected Object extractPrimaryKeyFromRow(AbstractRecord row, AbstractSession session) { |
| 886 |
return new Vector(0); |
880 |
return null; |
| 887 |
} |
881 |
} |
| 888 |
|
882 |
|
| 889 |
/** |
883 |
/** |
|
Lines 1700-1706
Link Here
|
| 1700 |
* INTERNAL: |
1694 |
* INTERNAL: |
| 1701 |
* An object is still in the collection, update it as it may have changed. |
1695 |
* An object is still in the collection, update it as it may have changed. |
| 1702 |
*/ |
1696 |
*/ |
| 1703 |
protected void objectUnchangedDuringUpdate(ObjectLevelModifyQuery query, Object object, Hashtable backupclones, CacheKey keys) throws DatabaseException, OptimisticLockException { |
1697 |
protected void objectUnchangedDuringUpdate(ObjectLevelModifyQuery query, Object object, Map backupclones, Object key) throws DatabaseException, OptimisticLockException { |
| 1704 |
objectUnchangedDuringUpdate(query, object); |
1698 |
objectUnchangedDuringUpdate(query, object); |
| 1705 |
} |
1699 |
} |
| 1706 |
|
1700 |
|
|
Lines 2282-2292
Link Here
|
| 2282 |
ContainerPolicy cp = this.containerPolicy; |
2276 |
ContainerPolicy cp = this.containerPolicy; |
| 2283 |
Object result = cp.containerInstance(pks.length); |
2277 |
Object result = cp.containerInstance(pks.length); |
| 2284 |
for (int index = 0; index < pks.length; ++index){ |
2278 |
for (int index = 0; index < pks.length; ++index){ |
| 2285 |
Vector pk = null; |
2279 |
Object pk = null; |
| 2286 |
if (getReferenceDescriptor().hasCMPPolicy()){ |
2280 |
if (getReferenceDescriptor().hasCMPPolicy()){ |
| 2287 |
pk = getReferenceDescriptor().getCMPPolicy().createPkVectorFromKey(pks[index], session); |
2281 |
pk = getReferenceDescriptor().getCMPPolicy().createPrimaryKeyFromId(pks[index], session); |
| 2288 |
}else{ |
2282 |
}else{ |
| 2289 |
pk = (Vector)pks[index]; |
2283 |
pk = pks[index]; |
| 2290 |
} |
2284 |
} |
| 2291 |
ReadObjectQuery query = new ReadObjectQuery(); |
2285 |
ReadObjectQuery query = new ReadObjectQuery(); |
| 2292 |
query.setReferenceClass(getReferenceClass()); |
2286 |
query.setReferenceClass(getReferenceClass()); |
|
Lines 2306-2335
Link Here
|
| 2306 |
|
2300 |
|
| 2307 |
Object value = this.containerPolicy.containerInstance(); |
2301 |
Object value = this.containerPolicy.containerInstance(); |
| 2308 |
// Extract the primary key of the source object, to filter only the joined rows for that object. |
2302 |
// Extract the primary key of the source object, to filter only the joined rows for that object. |
| 2309 |
Object sourceKey = getDescriptor().getObjectBuilder().extractPrimaryKeyFromRow(row, executionSession); |
2303 |
Object sourceKey = this.descriptor.getObjectBuilder().extractPrimaryKeyFromRow(row, executionSession); |
| 2310 |
CacheKey sourceCacheKey = new CacheKey(sourceKey); |
|
|
| 2311 |
// If the query was using joining, all of the result rows by primary key will have been computed. |
2304 |
// If the query was using joining, all of the result rows by primary key will have been computed. |
| 2312 |
List rows = joinManager.getDataResultsByPrimaryKey().get(sourceCacheKey); |
2305 |
List<AbstractRecord> rows = joinManager.getDataResultsByPrimaryKey().get(sourceKey); |
| 2313 |
int size = rows.size(); |
2306 |
int size = rows.size(); |
| 2314 |
if(size > 0) { |
2307 |
if (size > 0) { |
| 2315 |
// A nested query must be built to pass to the descriptor that looks like the real query execution would, |
2308 |
// A nested query must be built to pass to the descriptor that looks like the real query execution would, |
| 2316 |
// these should be cached on the query during prepare. |
2309 |
// these should be cached on the query during prepare. |
| 2317 |
ObjectLevelReadQuery nestedQuery = prepareNestedJoinQueryClone(row, rows, joinManager, sourceQuery, executionSession); |
2310 |
ObjectLevelReadQuery nestedQuery = prepareNestedJoinQueryClone(row, rows, joinManager, sourceQuery, executionSession); |
| 2318 |
|
2311 |
|
| 2319 |
// A set of target cache keys must be maintained to avoid duplicates from multiple 1-m joins. |
2312 |
// A set of target cache keys must be maintained to avoid duplicates from multiple 1-m joins. |
| 2320 |
Set targetCacheKeys = new HashSet(); |
2313 |
Set targetPrimaryKeys = new HashSet(); |
| 2321 |
|
2314 |
|
| 2322 |
ArrayList targetObjects = null; |
2315 |
ArrayList targetObjects = null; |
| 2323 |
ArrayList<AbstractRecord> targetRows = null; |
2316 |
ArrayList<AbstractRecord> targetRows = null; |
| 2324 |
boolean shouldAddAll = this.containerPolicy.shouldAddAll(); |
2317 |
boolean shouldAddAll = this.containerPolicy.shouldAddAll(); |
| 2325 |
if(shouldAddAll) { |
2318 |
if (shouldAddAll) { |
| 2326 |
targetObjects = new ArrayList(size); |
2319 |
targetObjects = new ArrayList(size); |
| 2327 |
targetRows = new ArrayList(size); |
2320 |
targetRows = new ArrayList(size); |
| 2328 |
} |
2321 |
} |
| 2329 |
|
2322 |
|
| 2330 |
// For each rows, extract the target row and build the target object and add to the collection. |
2323 |
// For each rows, extract the target row and build the target object and add to the collection. |
| 2331 |
for (int index = 0; index < size; index++) { |
2324 |
for (int index = 0; index < size; index++) { |
| 2332 |
AbstractRecord sourceRow = (AbstractRecord)rows.get(index); |
2325 |
AbstractRecord sourceRow = rows.get(index); |
| 2333 |
AbstractRecord targetRow = sourceRow; |
2326 |
AbstractRecord targetRow = sourceRow; |
| 2334 |
// The field for many objects may be in the row, |
2327 |
// The field for many objects may be in the row, |
| 2335 |
// so build the subpartion of the row through the computed values in the query, |
2328 |
// so build the subpartion of the row through the computed values in the query, |
|
Lines 2344-2359
Link Here
|
| 2344 |
return this.indirectionPolicy.valueFromRow(value); |
2337 |
return this.indirectionPolicy.valueFromRow(value); |
| 2345 |
} |
2338 |
} |
| 2346 |
|
2339 |
|
| 2347 |
CacheKey targetCacheKey = new CacheKey(targetKey); |
|
|
| 2348 |
// Only build/add the target object once, skip duplicates from multiple 1-m joins. |
2340 |
// Only build/add the target object once, skip duplicates from multiple 1-m joins. |
| 2349 |
if (!targetCacheKeys.contains(targetCacheKey)) { |
2341 |
if (!targetPrimaryKeys.contains(targetKey)) { |
| 2350 |
nestedQuery.setTranslationRow(targetRow); |
2342 |
nestedQuery.setTranslationRow(targetRow); |
| 2351 |
targetCacheKeys.add(targetCacheKey); |
2343 |
targetPrimaryKeys.add(targetKey); |
| 2352 |
Object targetObject = getReferenceDescriptor().getObjectBuilder().buildObject(nestedQuery, targetRow); |
2344 |
Object targetObject = getReferenceDescriptor().getObjectBuilder().buildObject(nestedQuery, targetRow); |
| 2353 |
Object targetMapKey = this.containerPolicy.buildKeyFromJoinedRow(targetRow, joinManager, nestedQuery, executionSession); |
2345 |
Object targetMapKey = this.containerPolicy.buildKeyFromJoinedRow(targetRow, joinManager, nestedQuery, executionSession); |
| 2354 |
nestedQuery.setTranslationRow(null); |
2346 |
nestedQuery.setTranslationRow(null); |
| 2355 |
if (targetMapKey == null){ |
2347 |
if (targetMapKey == null){ |
| 2356 |
if(shouldAddAll) { |
2348 |
if (shouldAddAll) { |
| 2357 |
targetObjects.add(targetObject); |
2349 |
targetObjects.add(targetObject); |
| 2358 |
targetRows.add(targetRow); |
2350 |
targetRows.add(targetRow); |
| 2359 |
} else { |
2351 |
} else { |
|
Lines 2364-2370
Link Here
|
| 2364 |
} |
2356 |
} |
| 2365 |
} |
2357 |
} |
| 2366 |
} |
2358 |
} |
| 2367 |
if(shouldAddAll) { |
2359 |
if (shouldAddAll) { |
| 2368 |
this.containerPolicy.addAll(targetObjects, value, executionSession, targetRows, nestedQuery); |
2360 |
this.containerPolicy.addAll(targetObjects, value, executionSession, targetRows, nestedQuery); |
| 2369 |
} |
2361 |
} |
| 2370 |
} |
2362 |
} |