| /* |
| * 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.transactionisolation; |
| |
| import org.eclipse.persistence.expressions.Expression; |
| import org.eclipse.persistence.expressions.ExpressionBuilder; |
| import org.eclipse.persistence.sessions.UnitOfWork; |
| import org.eclipse.persistence.testing.framework.AutoVerifyTestCase; |
| import org.eclipse.persistence.testing.models.employee.domain.Employee; |
| |
| |
| /** |
| * Tests the Session read refactoring / reading through the write connection |
| * properly feature. |
| * <p> |
| * Merge test to handle the following advanced scenario: |
| * <ul> |
| * <li> begin early transaction and read bill and Beatrix in UOW |
| * <li> change both names, and make Beatrix an employee of bill. |
| * <li> read bill and beatrix into the UOW. |
| * <li> commit. verify no clones in shared cache, and all pointers are valid. |
| * </ul> |
| * @author smcritch |
| */ |
| public class TransactionIsolationMergeCircularIndirectionTest extends AutoVerifyTestCase { |
| UnitOfWork unitOfWork; |
| Employee teamLead; |
| Employee freelance; |
| String teamLeadFirstName; |
| String freelanceFirstName; |
| |
| @Override |
| protected void setup() throws Exception { |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| unitOfWork = getSession().acquireUnitOfWork(); |
| } |
| |
| @Override |
| public void reset() throws Exception { |
| if (unitOfWork != null) { |
| unitOfWork.release(); |
| unitOfWork = null; |
| } |
| if (teamLead != null) { |
| unitOfWork = getSession().acquireUnitOfWork(); |
| Employee clone = (Employee)unitOfWork.readObject(teamLead); |
| clone.setFirstName(teamLeadFirstName); |
| Employee clone2 = (Employee)unitOfWork.readObject(freelance); |
| clone2.setFirstName(freelanceFirstName); |
| clone2.setManager(null); |
| unitOfWork.commit(); |
| unitOfWork = null; |
| teamLeadFirstName = null; |
| teamLead = null; |
| freelance = null; |
| freelanceFirstName = null; |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| } |
| } |
| |
| @Override |
| public void test() { |
| unitOfWork.beginEarlyTransaction(); |
| |
| ExpressionBuilder builder = new ExpressionBuilder(); |
| Expression expression = builder.get("gender").equal("Male"); |
| Employee teamLeadClone = (Employee)unitOfWork.readObject(Employee.class, expression); |
| teamLeadClone.setFirstName("Bill"); |
| |
| // By picking a male + female guaranteed to be different. |
| builder = new ExpressionBuilder(); |
| expression = builder.get("manager").isNull().and(builder.get("gender").equal("Female")); |
| Employee freelanceClone = (Employee)unitOfWork.readObject(Employee.class, expression); |
| freelanceClone.setFirstName("Beatrix"); |
| |
| teamLeadClone.addManagedEmployee(freelanceClone); |
| |
| // Due to the isolation it is possible to read the original values last. |
| // Identity should not be lost when the uow commits. |
| teamLead = (Employee)getSession().readObject(teamLeadClone); |
| teamLeadFirstName = teamLead.getFirstName(); |
| |
| freelance = (Employee)getSession().readObject(freelanceClone); |
| freelanceFirstName = freelance.getFirstName(); |
| |
| unitOfWork.commit(); |
| unitOfWork = null; |
| |
| Employee newTeamLead = (Employee)getSession().getIdentityMapAccessor().getFromIdentityMap(teamLeadClone); |
| strongAssert(newTeamLead == teamLead, |
| "The previous original should have been merged into the shared cache."); |
| strongAssert(newTeamLead.managedEmployees.isInstantiated(), |
| "The valueholder [managedEmployees] in the shared cache should be triggered now."); |
| |
| Employee newFreelance = (Employee)getSession().getIdentityMapAccessor().getFromIdentityMap(freelanceClone); |
| strongAssert(newFreelance == freelance, "Identity was lost on managed employees accross the 1-1"); |
| strongAssert(newTeamLead.getManagedEmployees().contains(freelance), |
| "teamLead is not pointing to the shared cache version of its new employee."); |
| strongAssert(newFreelance.manager.isInstantiated(), |
| "The valueholder [manager] in the shared cache should be triggered now."); |
| strongAssert(newFreelance.getManager() == newTeamLead, |
| "freelance is not pointing to the shared cache version of its new manager."); |
| } |
| } |