| /* |
| * 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: |
| Two threads(here we use two UOWs to simulate two threads) read in the same emplyee |
| object. The first thread updates employee's address(relationship) and commits. The |
| second thread updates the emplyee's salary(non-relationship attribute based on |
| where the emplyee lives)and commits. No exception is thrown but the updated salary |
| is invalid. If the first thread forces update the version value of the employee, an |
| optimistic lock exception is thrown in the second thread. |
| |
| (Version locking stores in the Object) |
| Test 1: (Correctly use method forceUpdateToVersionField()) |
| UOW1 updates employee's address, |
| calls forceUpdateToVersionField(Object cloneFromUOW1,true) and commits. |
| UOW2 updates the employee's salary and commits. |
| The test verified an optimistic lock exception is thrown in UOW2. |
| |
| Test 2: (forceUpdateToVersionField() doesn't effect read-only UOW) |
| UOW1 updates employee's address, |
| calls forceUpdateToVersionField(Object cloneFromUOW1,true) and commits. |
| UOW2 has only read-operation and commits. |
| The test verified no optimistic lock exception is thrown in UOW2. |
| |
| Test 3: (Test method removeForceUpdateToVersionField()) |
| UOW1 updates employee's address, |
| calls forceUpdateToVersionField(cloneFromUOW1,true),COMMIT&RESUMEs. |
| It calls removeForceUpdateToVersionField(cloneFromUOW1), |
| updates employee's address again and commits. |
| UOW2 reads employee after the first commit of UOW1,updates the emplyee's salary |
| and commits. |
| The test verified no optimistic lock exception is thrown in UOW2. |
| |
| Test 4: (Demonstrate the result when no using forceUpdateToVersionField()) |
| UOW1 updates employee's address, commits. |
| UOW2 updates the employee's salary and commits. |
| The test verified no optimistic lock exception is thrown in UOW2. |
| */ |
| public class FUVLVersionLockInObjectTest extends TransactionalTestCase { |
| boolean exceptionCaught = false; |
| int testnumber; |
| |
| public FUVLVersionLockInObjectTest(int anInt) { |
| testnumber = anInt; |
| setName(getName() + "(Test" + anInt + ")"); |
| switch (testnumber) { |
| case 1: |
| setDescription("Correctly use method forceUpdateToVersionField()"); |
| break; |
| case 2: |
| setDescription("forceUpdateToVersionField() doesn't effect read-only UOW"); |
| break; |
| case 3: |
| setDescription("Test method removeForceUpdateToVersionField()"); |
| break; |
| case 4: |
| setDescription("Demonstrate the result when no using forceUpdateToVersionField()"); |
| 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); |
| |
| EmployeeVLIO emp = (EmployeeVLIO)getSession().readObject(EmployeeVLIO.class, exp); |
| |
| uow1 = getSession().acquireUnitOfWork(); |
| uow2 = getSession().acquireUnitOfWork(); |
| EmployeeVLIO clone1 = (EmployeeVLIO)uow1.registerObject(emp); |
| EmployeeVLIO clone2 = (EmployeeVLIO)uow2.registerObject(emp); |
| |
| uow1.forceUpdateToVersionField(clone1, true); |
| clone1.getAddress().setStreet("4 Hutton Centre,Suite 900"); |
| clone1.getAddress().setCity("Santa Ana"); |
| clone1.getAddress().setProvince("CA"); |
| clone1.getAddress().setCountry("USA"); |
| clone1.getAddress().setPostalCode("92797"); |
| uow1.commit(); |
| |
| clone2.setSalary(clone2.getSalary() + 200); |
| try { |
| uow2.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); |
| |
| EmployeeVLIO emp = (EmployeeVLIO)getSession().readObject(EmployeeVLIO.class, exp); |
| |
| uow1 = getSession().acquireUnitOfWork(); |
| uow2 = getSession().acquireUnitOfWork(); |
| EmployeeVLIO clone1 = (EmployeeVLIO)uow1.registerObject(emp); |
| EmployeeVLIO clone2 = (EmployeeVLIO)uow2.registerObject(emp); |
| |
| uow1.forceUpdateToVersionField(clone1, true); |
| clone1.getAddress().setStreet("4 Hutton Centre,Suite 900"); |
| clone1.getAddress().setCity("Santa Ana"); |
| clone1.getAddress().setProvince("CA"); |
| clone1.getAddress().setCountry("USA"); |
| clone1.getAddress().setPostalCode("92797"); |
| uow1.commit(); |
| |
| // uow2 has only read-operation here |
| //... |
| try { |
| uow2.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); |
| |
| EmployeeVLIO emp = (EmployeeVLIO)getSession().readObject(EmployeeVLIO.class, exp); |
| |
| uow1 = getSession().acquireUnitOfWork(); |
| EmployeeVLIO clone1 = (EmployeeVLIO)uow1.registerObject(emp); |
| |
| uow1.forceUpdateToVersionField(clone1, true); |
| clone1.getAddress().setStreet("100 Young Street"); |
| clone1.getAddress().setCity("Toronto"); |
| clone1.getAddress().setProvince("ON"); |
| clone1.getAddress().setCountry("CANADA"); |
| clone1.getAddress().setPostalCode("K489Y7"); |
| uow1.commitAndResume(); |
| uow1.removeForceUpdateToVersionField(clone1); |
| |
| uow2 = getSession().acquireUnitOfWork(); |
| EmployeeVLIO clone2 = (EmployeeVLIO)uow2.registerObject(emp); |
| |
| clone1.getAddress().setStreet("4 Hutton Centre,Suite 900"); |
| clone1.getAddress().setCity("Santa Ana"); |
| clone1.getAddress().setProvince("CA"); |
| clone1.getAddress().setCountry("USA"); |
| clone1.getAddress().setPostalCode("92797"); |
| uow1.commit(); |
| |
| clone2.setSalary(clone2.getSalary() + 200); |
| try { |
| uow2.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); |
| |
| EmployeeVLIO emp = (EmployeeVLIO)getSession().readObject(EmployeeVLIO.class, exp); |
| |
| uow1 = getSession().acquireUnitOfWork(); |
| uow2 = getSession().acquireUnitOfWork(); |
| EmployeeVLIO clone1 = (EmployeeVLIO)uow1.registerObject(emp); |
| EmployeeVLIO clone2 = (EmployeeVLIO)uow2.registerObject(emp); |
| |
| clone1.getAddress().setStreet("4 Hutton Centre,Suite 900"); |
| clone1.getAddress().setCity("Santa Ana"); |
| clone1.getAddress().setProvince("CA"); |
| clone1.getAddress().setCountry("USA"); |
| clone1.getAddress().setPostalCode("92797"); |
| uow1.commit(); |
| |
| clone2.setSalary(clone2.getSalary() + 200); |
| try { |
| uow2.commit(); |
| } catch (OptimisticLockException exception) { |
| exceptionCaught = true; |
| } |
| } |
| |
| @Override |
| protected void verify() { |
| switch (testnumber) { |
| case 1: |
| if (!exceptionCaught) |
| throw new TestErrorException("No Optimistic Lock exception was thrown"); |
| break; |
| case 2: |
| case 3: |
| case 4: |
| if (exceptionCaught) |
| throw new TestErrorException("Optimistic Lock exception should not have been thrown"); |
| break; |
| default: |
| break; |
| } |
| } |
| } |