| /* |
| * 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.forceupdate; |
| |
| import org.eclipse.persistence.sessions.*; |
| import org.eclipse.persistence.exceptions.*; |
| import org.eclipse.persistence.expressions.*; |
| import org.eclipse.persistence.testing.framework.*; |
| import org.eclipse.persistence.testing.models.forceupdate.*; |
| |
| /** |
| Scenario: |
| One thread reads in two objects, Employee and Address. It begins to recalculate employee's |
| Salary based on the employee's office address. Another thread changes the employee's address. Then |
| the first commits. No exception would be thrown, but the entire calculation would be invalid. |
| If the user forces optimistic locking check of the Address in the first thread, an optimistic |
| lock exception is thrown.(here we use two UOWs to simulate two threads) |
| |
| (Version locking stores in the Cache) |
| Test 1:(Correctly use method forceUpdateToVersionField() with NOP) |
| UOW1 calculates employee's salary based on the emplyee's office address, |
| calls forceUpdateToVersionField(Object addressCloneFromUOW1,false). |
| UOW2 updates the employee's address and commits. |
| UOW1 commits. |
| The test verified an optimistic lock exception is thrown in UOW1. |
| |
| Test 2: (forceUpdateToVersionField() with NOP effects read-only UOW) |
| UOW1 has only read-operation, |
| calls forceUpdateToVersionField(Object addressCloneFromUOW1,false) and commits. |
| UOW2 updates the emplyee's address and commits. |
| UOW1 commits. |
| The test verified an optimistic lock exception is thrown in UOW1. |
| |
| Test 3: (Test method removeForceUpdateToVersionField()) |
| UOW1 calculates employee's salary based on the emplyee's office address, |
| calls forceUpdateToVersionField(Object addressCloneFromUOW1,false), |
| calls removeForceUpdateToVersionField(Object addressCloneFromUOW1). |
| UOW2 updates the employee's address and commits. |
| UOW1 commits. |
| The test verified no optimistic lock exception is thrown in UOW1. |
| |
| Test 4: (Demonstrate the result when no using forceUpdateToVersionField() with NOP ) |
| UOW1 calculates employee's salary based on the emplyee's office address, |
| UOW2 updates the employee's address and commits. |
| UOW1 commits. |
| The test verified no optimistic lock exception is thrown in UOW1. |
| */ |
| public class FUVLNopVersionLockInCacheTest extends TransactionalTestCase { |
| boolean exceptionCaught = false; |
| int testnumber; |
| |
| public FUVLNopVersionLockInCacheTest(int anInt) { |
| testnumber = anInt; |
| setName(getName() + "(Test" + anInt + ")"); |
| switch (testnumber) { |
| case 1: |
| setDescription("Correctly use method forceUpdateToVersionField() with NOP"); |
| break; |
| case 2: |
| setDescription("forceUpdateToVersionField() with NOP doesn't effect read-only UOW"); |
| break; |
| case 3: |
| setDescription("Test method removeForceUpdateToVersionField()"); |
| break; |
| case 4: |
| setDescription("Demonstrate the result when no using forceUpdateToVersionField() with NOP"); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| @Override |
| public void test() { |
| switch (testnumber) { |
| case 1: |
| test1(); |
| break; |
| case 2: |
| test2(); |
| break; |
| case 3: |
| test3(); |
| break; |
| case 4: |
| test4(); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| public void test1() { |
| UnitOfWork uow1, uow2; |
| |
| ExpressionBuilder bldr = new ExpressionBuilder(); |
| Expression exp1 = bldr.get("firstName").equal("Bob"); |
| Expression exp2 = bldr.get("lastName").equal("Smith"); |
| Expression exp = exp1.and(exp2); |
| |
| EmployeeVLIC emp = (EmployeeVLIC)getSession().readObject(EmployeeVLIC.class, exp); |
| |
| uow1 = getSession().acquireUnitOfWork(); |
| uow2 = getSession().acquireUnitOfWork(); |
| EmployeeVLIC clone1 = (EmployeeVLIC)uow1.registerObject(emp); |
| EmployeeVLIC clone2 = (EmployeeVLIC)uow2.registerObject(emp); |
| |
| uow1.forceUpdateToVersionField(clone1.getAddress(), false); |
| //caculate salary based on office address |
| if (clone1.getAddress().getCountry() == "Canada") { |
| clone1.setSalary(clone1.getSalary() + 200); |
| } |
| |
| clone2.getAddress().setStreet("4 Hutton Centre,Suite 900"); |
| clone2.getAddress().setCity("Santa Ana"); |
| clone2.getAddress().setProvince("CA"); |
| clone2.getAddress().setCountry("USA"); |
| clone2.getAddress().setPostalCode("92797"); |
| uow2.commit(); |
| |
| try { |
| uow1.commit(); |
| } catch (OptimisticLockException exception) { |
| exceptionCaught = true; |
| } |
| } |
| |
| public void test2() { |
| UnitOfWork uow1, uow2; |
| |
| ExpressionBuilder bldr = new ExpressionBuilder(); |
| Expression exp1 = bldr.get("firstName").equal("Bob"); |
| Expression exp2 = bldr.get("lastName").equal("Smith"); |
| Expression exp = exp1.and(exp2); |
| |
| EmployeeVLIC emp = (EmployeeVLIC)getSession().readObject(EmployeeVLIC.class, exp); |
| |
| uow1 = getSession().acquireUnitOfWork(); |
| uow2 = getSession().acquireUnitOfWork(); |
| EmployeeVLIC clone1 = (EmployeeVLIC)uow1.registerObject(emp); |
| EmployeeVLIC clone2 = (EmployeeVLIC)uow2.registerObject(emp); |
| |
| uow1.forceUpdateToVersionField(clone1.getAddress(), false); |
| // uow1 has only read-operation here |
| //... |
| |
| clone2.getAddress().setStreet("4 Hutton Centre,Suite 900"); |
| clone2.getAddress().setCity("Santa Ana"); |
| clone2.getAddress().setProvince("CA"); |
| clone2.getAddress().setCountry("USA"); |
| clone2.getAddress().setPostalCode("92797"); |
| uow2.commit(); |
| |
| try { |
| uow1.commit(); |
| } catch (OptimisticLockException exception) { |
| exceptionCaught = true; |
| } |
| } |
| |
| public void test3() { |
| UnitOfWork uow1, uow2; |
| |
| ExpressionBuilder bldr = new ExpressionBuilder(); |
| Expression exp1 = bldr.get("firstName").equal("Bob"); |
| Expression exp2 = bldr.get("lastName").equal("Smith"); |
| Expression exp = exp1.and(exp2); |
| |
| EmployeeVLIC emp = (EmployeeVLIC)getSession().readObject(EmployeeVLIC.class, exp); |
| |
| uow1 = getSession().acquireUnitOfWork(); |
| uow2 = getSession().acquireUnitOfWork(); |
| EmployeeVLIC clone1 = (EmployeeVLIC)uow1.registerObject(emp); |
| EmployeeVLIC clone2 = (EmployeeVLIC)uow2.registerObject(emp); |
| |
| uow1.forceUpdateToVersionField(clone1.getAddress(), false); |
| uow1.removeForceUpdateToVersionField(clone1.getAddress()); |
| //caculate salary based on office address |
| if (clone1.getAddress().getCountry() == "Canada") { |
| clone1.setSalary(clone1.getSalary() + 200); |
| } |
| |
| clone2.getAddress().setStreet("4 Hutton Centre,Suite 900"); |
| clone2.getAddress().setCity("Santa Ana"); |
| clone2.getAddress().setProvince("CA"); |
| clone2.getAddress().setCountry("USA"); |
| clone2.getAddress().setPostalCode("92797"); |
| uow2.commit(); |
| |
| try { |
| uow1.commit(); |
| } catch (OptimisticLockException exception) { |
| exceptionCaught = true; |
| } |
| } |
| |
| public void test4() { |
| UnitOfWork uow1, uow2; |
| |
| ExpressionBuilder bldr = new ExpressionBuilder(); |
| Expression exp1 = bldr.get("firstName").equal("Bob"); |
| Expression exp2 = bldr.get("lastName").equal("Smith"); |
| Expression exp = exp1.and(exp2); |
| |
| EmployeeVLIC emp = (EmployeeVLIC)getSession().readObject(EmployeeVLIC.class, exp); |
| |
| uow1 = getSession().acquireUnitOfWork(); |
| uow2 = getSession().acquireUnitOfWork(); |
| EmployeeVLIC clone1 = (EmployeeVLIC)uow1.registerObject(emp); |
| EmployeeVLIC clone2 = (EmployeeVLIC)uow2.registerObject(emp); |
| |
| //caculate salary based on office address |
| if (clone1.getAddress().getCountry() == "Canada") { |
| clone1.setSalary(clone1.getSalary() + 200); |
| } |
| |
| clone2.getAddress().setStreet("4 Hutton Centre,Suite 900"); |
| clone2.getAddress().setCity("Santa Ana"); |
| clone2.getAddress().setProvince("CA"); |
| clone2.getAddress().setCountry("USA"); |
| clone2.getAddress().setPostalCode("92797"); |
| uow2.commit(); |
| |
| try { |
| uow1.commit(); |
| } catch (OptimisticLockException exception) { |
| exceptionCaught = true; |
| } |
| } |
| |
| @Override |
| protected void verify() { |
| switch (testnumber) { |
| case 1: |
| case 2: |
| if (!exceptionCaught) |
| throw new TestErrorException("No Optimistic Lock exception was thrown"); |
| break; |
| case 3: |
| case 4: |
| if (exceptionCaught) |
| throw new TestErrorException("Optimistic Lock exception should not have been thrown"); |
| break; |
| default: |
| break; |
| } |
| } |
| } |