| /* |
| * 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.unitofwork; |
| |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy; |
| import org.eclipse.persistence.sessions.UnitOfWork; |
| import org.eclipse.persistence.testing.framework.AutoVerifyTestCase; |
| import org.eclipse.persistence.testing.framework.TestWarningException; |
| import org.eclipse.persistence.testing.models.employee.domain.Employee; |
| |
| |
| /** |
| * <P><B>Purpose</B>: To make sure that reading an object containing a bidirectional |
| * relationship with a value holder does not cause an infinite loop when |
| * using NoIdentityMap. |
| * |
| * <P><B>Motivation</B>: This test was written to fix a bug. When using NoIdentityMap, if an |
| * Employee (which has a bidirectional relationship with a ValueHolder |
| * managedEmployees) is read, it checks to see if a managedEmployee is in |
| * the cache, and since there is no cache, reads the managedEmployee. When |
| * the managedEmployee is read, it too checks to see if its manager is in the |
| * cache, and since there is none, reads its manager, hence causing an |
| * infinite loop. |
| * |
| * <P><B>Design</B>: First, the Employee descriptor is changed to use NoIdentityMap. Next, a |
| * Unit Of Work is acquired, and an attempt is made to read and change an Employee. |
| * After the Employee is read, the Employee descriptor is reset to its original state. |
| * |
| * <P><B>Responsibilities</B>: Verify that the above conditions do not cause an infinite loop. |
| * |
| * <P><B>Features Used</B>: Unit Of Work, (No) Identity Map |
| * |
| * <P><B>Paths Covered</B>: Attempting to read a org.eclipse.persistence.testing.models.employee.domain.Employee covers: |
| * <UL> |
| * <LI><CODE>manager</CODE> 1:1 Mapping |
| * <LI><CODE>managedEmployees</CODE> 1:M Mapping |
| * </UL> |
| */ |
| public class NoIMWithValueHolderTest extends AutoVerifyTestCase { |
| public UnitOfWork unitOfWork; |
| public ClassDescriptor originalEmployeeDescriptor; |
| public OptimisticLockingPolicy policy; |
| |
| public NoIMWithValueHolderTest() { |
| super(); |
| setDescription("This test case should NOT get into an infinite loop (if you're reading this, it passed)."); |
| } |
| |
| @Override |
| public void reset() { |
| if (getSession() instanceof org.eclipse.persistence.sessions.remote.RemoteSession) { |
| return; |
| } |
| getAbstractSession().rollbackTransaction(); |
| // Reset the original Employee descriptor |
| originalEmployeeDescriptor = getSession().getClassDescriptor(Employee.class); |
| originalEmployeeDescriptor.useFullIdentityMap(); |
| originalEmployeeDescriptor.setOptimisticLockingPolicy(this.policy); |
| originalEmployeeDescriptor.getQueryManager().checkCacheForDoesExist(); |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| } |
| |
| @Override |
| public void setup() { |
| if (getSession() instanceof org.eclipse.persistence.sessions.remote.RemoteSession) { |
| throw new TestWarningException("This test cannot be run through the remote."); |
| } |
| getAbstractSession().beginTransaction(); |
| // Save the original Employee descriptor |
| originalEmployeeDescriptor = getSession().getClassDescriptor(Employee.class); |
| originalEmployeeDescriptor.useNoIdentityMap(); |
| this.policy = originalEmployeeDescriptor.getOptimisticLockingPolicy(); |
| originalEmployeeDescriptor.setOptimisticLockingPolicy(null); |
| originalEmployeeDescriptor.getQueryManager().assumeExistenceForDoesExist(); |
| } |
| |
| @Override |
| protected void test() { |
| // Attempt to read and change an Employee |
| unitOfWork = getSession().acquireUnitOfWork(); |
| Employee employee = (Employee)unitOfWork.readObject(Employee.class); |
| employee.setFirstName("Yahoo"); |
| employee.setLastName("Serious"); |
| employee.setMale(); |
| unitOfWork.commit(); |
| } |
| } |