blob: 4059c3daa97fea886273b33b22e5e196f25f675f [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;
import java.util.Vector;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.testing.models.employee.domain.*;
/**
* Test for bug 3568141: CONFORMING QUERY DOESN'T RETURN CORRECT ROWS WHEN INDIRECTION IS USED
* <p>
* We decoupled the in-memory query indirection policy from conforming, making
* it impossible for a user to set shouldTriggerIndirection() on a conforming
* query.
* <p>
* This broke a lot of customers, so we had to undo what we did.
*
* @author smcritch
*/
public class ConformingShouldTriggerIndirectionTest extends AutoVerifyTestCase {
public ConformingShouldTriggerIndirectionTest() {
}
@Override
public void test() throws Exception {
UnitOfWork uow = getSession().acquireUnitOfWork();
ExpressionBuilder proj = new ExpressionBuilder();
Expression outOfOttawaProjectsExp = proj.get("teamLeader").get("address").get("city").notEqual("Ottawa");
ReadAllQuery originalQuery = new ReadAllQuery(Project.class);
originalQuery.setSelectionCriteria(outOfOttawaProjectsExp);
Vector outOfOttawaProjects = (Vector)uow.executeQuery(originalQuery);
ExpressionBuilder emp = new ExpressionBuilder();
Expression ottawaEmpsExp = emp.get("address").get("city").equal("Ottawa");
ReadAllQuery employeeQuery = new ReadAllQuery(Employee.class);
employeeQuery.setSelectionCriteria(ottawaEmpsExp);
Vector ottawaEmps = (Vector)uow.executeQuery(employeeQuery);
Project conformingProject = (Project)outOfOttawaProjects.elementAt(0);
Employee conformingEmp = (Employee)ottawaEmps.elementAt(0);
// Now this project will no longer conform.
// The crux is that this project's teamleader's address was changed
// without triggering all valueholders. Hence the default heuristic
// conforming would assume that project has not changed relative to the
// query.
// The 2 levels of indirection were needed because setting an attribute
// (changing an object) automatically triggers one level of indirection.
conformingProject.setTeamLeader(conformingEmp);
// Now execute the original query again as a conforming query. This
// time the project that was changed should get dropped from the result.
ReadAllQuery conformingQuery = originalQuery;
conformingQuery.setInMemoryQueryIndirectionPolicy(new InMemoryQueryIndirectionPolicy(InMemoryQueryIndirectionPolicy.SHOULD_TRIGGER_INDIRECTION));
conformingQuery.conformResultsInUnitOfWork();
Vector conformingProjects = (Vector)uow.executeQuery(conformingQuery);
if ((conformingProjects.size() + 1) != outOfOttawaProjects.size()) {
throw new TestErrorException("The result was not conformed. Original: " + outOfOttawaProjects + " Conforming: " + conformingProjects);
}
}
}