| /* |
| * 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 org.eclipse.persistence.testing.framework.*; |
| import org.eclipse.persistence.testing.models.employee.domain.*; |
| import org.eclipse.persistence.queries.*; |
| import org.eclipse.persistence.expressions.*; |
| |
| /** |
| * Abstract superclass for testing various cascading features |
| * Subclasses must implement setTestConfiguration(). |
| * |
| * @author Peter O'Blenis |
| */ |
| public abstract class CascadingTest extends TestCase { |
| |
| /* |
| * The following varaibles must be set by the subclass in the setTestConfiguration() method |
| */ |
| |
| //Name of the test to be displayed in error messages |
| protected String m_szTestName = null; |
| |
| //Maintain cache for test |
| protected boolean m_bMaintainCache = false; |
| |
| //Type of cascading (See constants below) |
| protected int m_nCascadeType = 0; |
| |
| //Cascading Constants |
| protected static final int NO_CASCADE = 0; |
| protected static final int CASCADE_PRIVATE = 1; |
| protected static final int CASCADE_ALL = 2; |
| protected Employee employeeFromDatabase; |
| protected Employee m_reloadedEmployee; |
| protected String m_szManagedEmployee; |
| protected String m_szFirstName; |
| protected String m_szPhoneNumber; |
| |
| public CascadingTest() { |
| super(); |
| setTestConfiguration(); |
| } |
| |
| protected void cascadeCheck() { |
| ReadObjectQuery query = new ReadObjectQuery(); |
| query.setSelectionObject(employeeFromDatabase); |
| |
| //If MaintainCache is turned off then nothing in the cached object should have changed. |
| if (!m_bMaintainCache) { |
| if (!m_reloadedEmployee.getFirstName().equals(m_szFirstName)) { |
| throw new TestErrorException(m_szTestName + " test failed on firstName"); |
| } |
| |
| //PhoneNumber should have been refreshed from the database. Ensure that it was not refreshed from cache |
| if (m_nCascadeType == CASCADE_PRIVATE) { |
| if (!((PhoneNumber)m_reloadedEmployee.getPhoneNumbers().elementAt(0)).getType().equals(m_szPhoneNumber)) { |
| throw new TestErrorException(m_szTestName + ": private cascaded parts were not refreshed from db"); |
| } |
| } |
| |
| //ManagedEmployee name should have been refreshed from the database. Ensure that it was not refreshed from cache |
| if (m_nCascadeType == CASCADE_ALL) { |
| if (!((Employee)m_reloadedEmployee.getManagedEmployees().elementAt(0)).getFirstName().equals(m_szManagedEmployee)) { |
| throw new TestErrorException(m_szTestName + ": public cascaded parts were not refreshed from db"); |
| } |
| } |
| |
| for (int loop = 0; loop < 5; loop++) { |
| // This test was randomloy failing because TopLink avoids refreshes within the millisecond |
| // Changing to do a shallow refresh after to make the time to the other refresh less and more likely to fail. |
| // so more consistent. |
| employeeFromDatabase.setFirstName("Refresh too fast"); |
| ReadObjectQuery refreshQuery = new ReadObjectQuery(employeeFromDatabase); |
| refreshQuery.refreshIdentityMapResult(); |
| getSession().executeQuery(refreshQuery); |
| |
| if (!employeeFromDatabase.getFirstName().equals(m_szFirstName)) { |
| throw new TestErrorException(m_szTestName + ": test failed on firstName loop-" + loop); |
| } |
| } |
| } |
| //If MaintainCache is turn on then the cached object should have changed according to the cascade policy |
| else { |
| if (!employeeFromDatabase.getFirstName().equals(m_szFirstName)) { |
| throw new TestErrorException(m_szTestName + ": test failed on firstName"); |
| } |
| |
| //Check that private cascaded objects in the cache have been refreshed with db data |
| if (m_nCascadeType == CASCADE_PRIVATE) {// || (m_nCascadeType == CASCADE_ALL)) |
| if (!((PhoneNumber)employeeFromDatabase.getPhoneNumbers().elementAt(0)).getType().equals(m_szPhoneNumber)) { |
| throw new TestErrorException(m_szTestName + ": private cache data not refreshed from db"); |
| } |
| } |
| |
| //Check that all cascaded objects in the cache have been refreshed with db data |
| if (m_nCascadeType == CASCADE_ALL) { |
| if (!((Employee)employeeFromDatabase.getManagedEmployees().elementAt(0)).getFirstName().equals(m_szManagedEmployee)) { |
| throw new TestErrorException(m_szTestName + ":public cache data not refreshed from db"); |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void reset() { |
| // Because the name of the employee was changed, clear the cache. |
| getSession().getIdentityMapAccessor().initializeIdentityMaps(); |
| } |
| |
| protected void setConfiguration(String szTestName, boolean bMaintainCache, int nCascadeSetting) { |
| m_szTestName = szTestName; |
| m_bMaintainCache = bMaintainCache; |
| m_nCascadeType = nCascadeSetting; |
| } |
| |
| abstract void setTestConfiguration(); |
| |
| @Override |
| protected void setup() { |
| //Fix bug 2722927 |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| //Check that the subclass implemented setTestConfiguration() correctly |
| if (m_szTestName == null) { |
| throw new TestErrorException("CascadingTest: Subclass did not initialize test properly"); |
| } |
| |
| ExpressionBuilder expBldr = new ExpressionBuilder(); |
| Expression whatWeWant = expBldr.get("lastName").equal("May"); |
| employeeFromDatabase = (Employee)getSession().readObject(Employee.class, whatWeWant); |
| } |
| |
| @Override |
| public void test() { |
| m_szFirstName = employeeFromDatabase.getFirstName(); |
| m_szPhoneNumber = ((PhoneNumber)employeeFromDatabase.getPhoneNumbers().elementAt(0)).getType(); |
| m_szManagedEmployee = ((Employee)employeeFromDatabase.getManagedEmployees().elementAt(0)).getFirstName(); |
| |
| //Change the employees name |
| employeeFromDatabase.setFirstName("Foobar"); |
| |
| //Change the first phone number |
| ((PhoneNumber)employeeFromDatabase.getPhoneNumbers().elementAt(0)).setType("FooNumber"); |
| |
| //Change the manager |
| ((Employee)employeeFromDatabase.getManagedEmployees().elementAt(0)).setFirstName("MrFoobar"); |
| } |
| |
| @Override |
| protected void verify() { |
| ReadObjectQuery query = new ReadObjectQuery(); |
| query.setSelectionObject(employeeFromDatabase); |
| |
| //Set cache mode |
| if (m_bMaintainCache) { |
| // query.maintainCache(); |
| query.refreshIdentityMapResult(); |
| } else { |
| query.dontMaintainCache(); |
| } |
| |
| //Set Cascade mode |
| switch (m_nCascadeType) { |
| case CASCADE_PRIVATE: |
| query.cascadePrivateParts(); |
| break; |
| case CASCADE_ALL: |
| query.cascadeAllParts(); |
| break; |
| default: |
| query.dontCascadeParts(); |
| } |
| |
| //Perform the query |
| m_reloadedEmployee = (Employee)getSession().executeQuery(query); |
| |
| //Check that the expected changes (or lack there of) took place in the cached object |
| cascadeCheck(); |
| } |
| } |