use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.
the class NestedDefaultFetchGroupTests method internalFindMinEmployee.
void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
int minId = minEmployeeIdWithAddressAndPhones(em);
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
boolean load = false;
boolean originalLoad = false;
if (!useLoadGroup) {
assertTrue(loadAddress == loadPhones);
load = loadAddress;
originalLoad = defaultEmployeeFG.shouldLoad();
if (load != originalLoad) {
defaultEmployeeFG.setShouldLoad(load);
}
}
try {
Employee emp;
if (useLoadGroup) {
LoadGroup lg = defaultEmployeeFG.toLoadGroup();
if (!loadAddress) {
lg.removeAttribute("address");
}
if (!loadPhones) {
lg.removeAttribute("phoneNumbers");
}
HashMap<String, Object> hints = new HashMap(1);
hints.put(QueryHints.LOAD_GROUP, lg);
emp = em.find(Employee.class, minId, hints);
} else {
emp = em.find(Employee.class, minId);
}
assertNotNull(emp);
int nExpected = 2;
if (loadAddress) {
nExpected++;
}
if (loadPhones) {
nExpected++;
}
assertEquals(nExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
boolean addressInstantiated = ((ValueHolderInterface) employeeDescriptor.getMappingForAttributeName("address").getAttributeValueFromObject(emp)).isInstantiated();
assertTrue(loadAddress == addressInstantiated);
boolean phonesInstantiated = ((IndirectCollection) employeeDescriptor.getMappingForAttributeName("phoneNumbers").getAttributeValueFromObject(emp)).isInstantiated();
assertTrue(loadPhones == phonesInstantiated);
emp.getAddress();
emp.getPhoneNumbers().size();
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertFetched(emp, defaultEmployeeFG);
assertFetchedAttribute(emp, "address");
assertFetchedAttribute(emp, "phoneNumbers");
// Check Address
FetchGroup fgAddress = defaultEmployeeFG.getGroup("address");
assertFetched(emp.getAddress(), fgAddress);
// Check phones
FetchGroup fgPhones = defaultEmployeeFG.getGroup("phoneNumbers");
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertFetched(phone, fgPhones);
}
} finally {
if (!useLoadGroup) {
if (load != originalLoad) {
defaultEmployeeFG.setShouldLoad(originalLoad);
}
}
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.
the class NestedDefaultFetchGroupTests method internalFindMinEmployee.
void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) {
EntityManager em = createEntityManager();
beginTransaction(em);
int minId = minEmployeeIdWithAddressAndPhones(em);
assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
boolean load = false;
boolean originalLoad = false;
if (!useLoadGroup) {
assertTrue(loadAddress == loadPhones);
load = loadAddress;
originalLoad = defaultEmployeeFG.shouldLoad();
if (load != originalLoad) {
defaultEmployeeFG.setShouldLoad(load);
}
}
try {
Employee emp;
if (useLoadGroup) {
LoadGroup lg = defaultEmployeeFG.toLoadGroup();
if (!loadAddress) {
lg.removeAttribute("address");
}
if (!loadPhones) {
lg.removeAttribute("phoneNumbers");
}
HashMap<String, Object> hints = new HashMap(1);
hints.put(QueryHints.LOAD_GROUP, lg);
emp = em.find(Employee.class, minId, hints);
} else {
emp = em.find(Employee.class, minId);
}
assertNotNull(emp);
int nExpected = 2;
if (loadAddress) {
nExpected++;
}
if (loadPhones) {
nExpected++;
}
assertEquals(nExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
boolean addressInstantiated = ((ValueHolderInterface) employeeDescriptor.getMappingForAttributeName("address").getAttributeValueFromObject(emp)).isInstantiated();
assertTrue(loadAddress == addressInstantiated);
boolean phonesInstantiated = ((IndirectCollection) employeeDescriptor.getMappingForAttributeName("phoneNumbers").getAttributeValueFromObject(emp)).isInstantiated();
assertTrue(loadPhones == phonesInstantiated);
emp.getAddress();
emp.getPhoneNumbers().size();
assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
assertFetched(emp, defaultEmployeeFG);
assertFetchedAttribute(emp, "address");
assertFetchedAttribute(emp, "phoneNumbers");
// Check Address
FetchGroup fgAddress = defaultEmployeeFG.getGroup("address");
assertFetched(emp.getAddress(), fgAddress);
// Check phones
FetchGroup fgPhones = defaultEmployeeFG.getGroup("phoneNumbers");
for (PhoneNumber phone : emp.getPhoneNumbers()) {
assertFetched(phone, fgPhones);
}
} finally {
if (!useLoadGroup) {
if (load != originalLoad) {
defaultEmployeeFG.setShouldLoad(originalLoad);
}
}
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.
the class JUnitJPQLComplexTestSuite method testJoinFetchWithJoin.
// Bug 303767 - fixed with Hermes.
// Test that the same attribute can be joined and join fetched.
public void testJoinFetchWithJoin() {
if (!isHermesParser()) {
warning("testJoinFetchWithJoin only works with Hermes");
return;
}
clearCache();
EntityManager em = createEntityManager();
Query query = em.createQuery("Select e from Employee e join fetch e.phoneNumbers join e.phoneNumbers p where p.areaCode <> '613'");
Employee employee = (Employee) query.getResultList().get(0);
if (isWeavingEnabled()) {
if ((employee.getPhoneNumbers() instanceof IndirectCollection) && !((IndirectCollection) employee.getPhoneNumbers()).isInstantiated()) {
fail("Join fetch did not occur.");
}
}
clearCache();
em.clear();
query = em.createQuery("Select e from Employee e join e.phoneNumbers p join fetch e.phoneNumbers where p.areaCode <> '613'");
employee = (Employee) query.getResultList().get(0);
if (isWeavingEnabled()) {
if ((employee.getPhoneNumbers() instanceof IndirectCollection) && !((IndirectCollection) employee.getPhoneNumbers()).isInstantiated()) {
fail("Join fetch did not occur.");
}
}
closeEntityManager(em);
}
use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.
the class DirectCollectionMapping method mergeChangesIntoObject.
/**
* INTERNAL:
* Merge changes from the source to the target object.
* Because this is a collection mapping, values are added to or removed from the
* collection based on the changeset
*/
@Override
public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
if (this.descriptor.getCachePolicy().isProtectedIsolation() && !this.isCacheable && !targetSession.isProtectedSession()) {
setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null)));
return;
}
ContainerPolicy containerPolicy = getContainerPolicy();
Object valueOfTarget = null;
AbstractSession session = mergeManager.getSession();
DirectCollectionChangeRecord directCollectionChangeRecord = (DirectCollectionChangeRecord) changeRecord;
// Check to see if the target has an instantiated collection
if ((isAttributeValueInstantiated(target)) && (!changeRecord.getOwner().isNew())) {
if (isSynchronizeOnMerge) {
valueOfTarget = getRealCollectionAttributeValueFromObject(target, session);
} else {
valueOfTarget = containerPolicy.cloneFor(getRealCollectionAttributeValueFromObject(target, session));
}
} else {
// if not create an instance of the collection
valueOfTarget = containerPolicy.containerInstance(directCollectionChangeRecord.getAddObjectMap().size());
}
if (!isAttributeValueInstantiated(target)) {
if (mergeManager.shouldMergeChangesIntoDistributedCache()) {
return;
}
for (Object iterator = containerPolicy.iteratorFor(getRealCollectionAttributeValueFromObject(source, session)); containerPolicy.hasNext(iterator); ) {
containerPolicy.addInto(containerPolicy.next(iterator, session), valueOfTarget, session);
}
} else {
Object synchronizationTarget = valueOfTarget;
// not the wrapper as the clone synchs on the delegate, see bug#5685287.
if (valueOfTarget instanceof IndirectCollection) {
synchronizationTarget = ((IndirectCollection) valueOfTarget).getDelegateObject();
if (((DirectCollectionChangeRecord) changeRecord).orderHasBeenRepaired() && (valueOfTarget instanceof IndirectList)) {
((IndirectList) valueOfTarget).setIsListOrderBrokenInDb(false);
}
}
if (isSynchronizeOnMerge) {
synchronized (synchronizationTarget) {
mergeAddRemoveChanges(valueOfTarget, synchronizationTarget, directCollectionChangeRecord, mergeManager, session);
}
} else {
mergeAddRemoveChanges(valueOfTarget, synchronizationTarget, directCollectionChangeRecord, mergeManager, session);
}
}
setRealAttributeValueInObject(target, valueOfTarget);
}
use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.
the class DirectMapMapping method mergeChangesIntoObject.
/**
* INTERNAL:
* Merge changes from the source to the target object.
* Because this is a collection mapping, values are added to or removed from the
* collection based on the changeset.
*/
@Override
public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
if (this.descriptor.getCachePolicy().isProtectedIsolation() && !this.isCacheable && !targetSession.isProtectedSession()) {
setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null)));
return;
}
Map valueOfTarget = null;
AbstractSession session = mergeManager.getSession();
// collect the changes into a vector
HashMap addObjects = ((DirectMapChangeRecord) changeRecord).getAddObjects();
HashMap removeObjects = ((DirectMapChangeRecord) changeRecord).getRemoveObjects();
// Check to see if the target has an instantiated collection
if ((isAttributeValueInstantiated(target)) && (!changeRecord.getOwner().isNew())) {
valueOfTarget = (Map) getRealCollectionAttributeValueFromObject(target, session);
} else {
// if not create an instance of the map
valueOfTarget = (Map) containerPolicy.containerInstance(addObjects.size());
}
if (!isAttributeValueInstantiated(target)) {
if (mergeManager.shouldMergeChangesIntoDistributedCache()) {
return;
}
Object valueOfSource = getRealCollectionAttributeValueFromObject(source, session);
for (Object iterator = containerPolicy.iteratorFor(valueOfSource); containerPolicy.hasNext(iterator); ) {
Map.Entry entry = (Map.Entry) containerPolicy.nextEntry(iterator, session);
containerPolicy.addInto(entry.getKey(), entry.getValue(), valueOfTarget, session);
}
} else {
Object synchronizationTarget = valueOfTarget;
// not the wrapper as the clone synchs on the delegate, see bug#5685287.
if (valueOfTarget instanceof IndirectCollection) {
synchronizationTarget = ((IndirectCollection) valueOfTarget).getDelegateObject();
}
synchronized (synchronizationTarget) {
// Next iterate over the changes and add them to the container
for (Iterator i = removeObjects.keySet().iterator(); i.hasNext(); ) {
Object keyToRemove = i.next();
containerPolicy.removeFrom(keyToRemove, null, valueOfTarget, session);
}
for (Iterator i = addObjects.keySet().iterator(); i.hasNext(); ) {
Object keyToAdd = i.next();
Object nextItem = addObjects.get(keyToAdd);
if (mergeManager.shouldMergeChangesIntoDistributedCache()) {
// bug#4458089 and 4454532- check if collection contains new item before adding during merge into distributed cache
if (!containerPolicy.contains(nextItem, valueOfTarget, session)) {
containerPolicy.addInto(keyToAdd, nextItem, valueOfTarget, session);
}
} else {
containerPolicy.addInto(keyToAdd, nextItem, valueOfTarget, session);
}
}
}
}
setRealAttributeValueInObject(target, valueOfTarget);
}
Aggregations