blob: 41eccfa1c5e0d655db79904b6141ba00ee679e7d [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.queries.optimization;
import java.util.Vector;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.models.mapping.Employee;
import org.eclipse.persistence.testing.framework.TestCase;
import org.eclipse.persistence.annotations.BatchFetchType;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
// bug 6690525: STACKOVERFLOWERROR UNDER READALLQUERY.EXECUTE
public class BatchReadingStackOverflowTest extends TestCase {
String firstName = "StackOverflowTest";
Employee emp_1;
ForeignReferenceMapping mappingToDisableBatchReadInReset;
BatchFetchType batchType;
public BatchReadingStackOverflowTest(BatchFetchType batchType) {
this.batchType = batchType;
setName(getName() + batchType);
}
@Override
protected void setup() throws Throwable {
if ((batchType == BatchFetchType.IN) && !getSession().getPlatform().isOracle()) {
throwWarning("Nested arrays not supported on this database");
}
// set readBatch to true on managedEmployees mapping
mappingToDisableBatchReadInReset = (ForeignReferenceMapping)getSession().getDescriptor(Employee.class).getMappingForAttributeName("managedEmployees");
if(mappingToDisableBatchReadInReset.shouldUseBatchReading()) {
// nothing to do - it already uses batch reading
mappingToDisableBatchReadInReset = null;
} else {
mappingToDisableBatchReadInReset.setUsesBatchReading(true);
mappingToDisableBatchReadInReset.setBatchFetchType(batchType);
mappingToDisableBatchReadInReset.getSelectionQuery().setIsPrepared(false);
((ReadAllQuery)mappingToDisableBatchReadInReset.getSelectionQuery()).setBatchFetchPolicy(null);
mappingToDisableBatchReadInReset.getDescriptor().getObjectBuilder().initializeBatchFetchedAttributes();
}
// create objects to be used by the test:
// emp_1 has two managed employees, each of them has one managed employee.
emp_1 = new Employee();
emp_1.firstName = firstName;
emp_1.lastName = "1";
emp_1.sex = "male";
emp_1.managedEmployees = new Vector(2);
Employee emp_1_1 = new Employee();
emp_1_1.firstName = firstName;
emp_1_1.lastName = "1_1";
emp_1_1.sex = "male";
emp_1_1.managedEmployees = new Vector(1);
emp_1.managedEmployees.add(emp_1_1);
emp_1_1.manager = emp_1;
Employee emp_1_2 = new Employee();
emp_1_2.firstName = firstName;
emp_1_2.lastName = "1_2";
emp_1_2.sex = "male";
emp_1_2.managedEmployees = new Vector(1);
emp_1.managedEmployees.add(emp_1_2);
emp_1_2.manager = emp_1;
Employee emp_1_1_1 = new Employee();
emp_1_1_1.firstName = firstName;
emp_1_1_1.lastName = "1_1_1";
emp_1_1_1.sex = "male";
emp_1_1.managedEmployees.add(emp_1_1_1);
emp_1_1_1.manager = emp_1_1;
Employee emp_1_2_1 = new Employee();
emp_1_2_1.firstName = firstName;
emp_1_2_1.lastName = "1_2_1";
emp_1_2_1.sex = "male";
emp_1_2.managedEmployees.add(emp_1_2_1);
emp_1_2_1.manager = emp_1_2;
// Begin transaction here and rollback it in reset.
((AbstractSession)getSession()).beginTransaction();
// write the objects into the db, merge them into session's cache.
UnitOfWork uow = getSession().acquireUnitOfWork();
uow.registerObject(emp_1);
uow.commit();
// now invalidate all the created objects in the session's cache
getSession().getIdentityMapAccessor().invalidateObject(emp_1);
getSession().getIdentityMapAccessor().invalidateObject(emp_1_1);
getSession().getIdentityMapAccessor().invalidateObject(emp_1_2);
getSession().getIdentityMapAccessor().invalidateObject(emp_1_1_1);
getSession().getIdentityMapAccessor().invalidateObject(emp_1_2_1);
}
@Override
protected void test() throws Throwable {
// query to read emp_1
ReadObjectQuery query = new ReadObjectQuery(Employee.class);
ExpressionBuilder builder = query.getExpressionBuilder();
Expression exp = builder.get("firstName").equal(firstName).and(builder.get("lastName").equal("1"));
query.setSelectionCriteria(exp);
// executing the query used to cause StackOverflow
Employee empRead = (Employee)getSession().executeQuery(query);
// the following line is provided just in case you need to put a break point after query execution
empRead.getManagedEmployees().size();
query = null;
}
@Override
public void reset() throws Throwable {
if(((AbstractSession)getSession()).isInTransaction()) {
((AbstractSession)getSession()).rollbackTransaction();
getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
}
if(mappingToDisableBatchReadInReset != null) {
mappingToDisableBatchReadInReset.setUsesBatchReading(false);
mappingToDisableBatchReadInReset.getSelectionQuery().setIsPrepared(false);
((ReadAllQuery)mappingToDisableBatchReadInReset.getSelectionQuery()).setBatchFetchPolicy(null);
mappingToDisableBatchReadInReset.getDescriptor().getObjectBuilder().initializeBatchFetchedAttributes();
mappingToDisableBatchReadInReset = null;
}
}
}