| /* |
| * Copyright (c) 1998, 2020 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: |
| // dminsky - initial API and implementation |
| package org.eclipse.persistence.testing.tests.jpa.advanced; |
| |
| import java.util.List; |
| |
| import jakarta.persistence.EntityManager; |
| import jakarta.persistence.LockModeType; |
| |
| import junit.framework.Test; |
| import junit.framework.TestSuite; |
| |
| import org.eclipse.persistence.sessions.server.ServerSession; |
| import org.eclipse.persistence.testing.framework.junit.JUnitTestCase; |
| import org.eclipse.persistence.testing.models.jpa.advanced.Address; |
| import org.eclipse.persistence.testing.models.jpa.advanced.AdvancedTableCreator; |
| |
| /** |
| * <p> |
| * <b>Purpose</b>: Test Pessimistic Locking Entity Refresh functionality. |
| * <p> |
| * <b>Description</b>: Test entity refresh functionality under different locking situations.<br> |
| * Implemented for EclipseLink bug: 409433 |
| */ |
| public class PessimisticLockEntityRefreshTestSuite extends JUnitTestCase { |
| |
| public PessimisticLockEntityRefreshTestSuite(String name) { |
| super(name); |
| } |
| |
| public static Test suite() { |
| TestSuite suite = new TestSuite("PessimisticLocking Entity Refresh TestSuite"); |
| if (!isJPA10()) { |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testSetup")); |
| |
| // test lock-on-find an object multiple times with the same lock type |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticWriteLockFind")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticReadLockFind")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticForceIncrementLockFind")); |
| |
| // test lock-on-find an object then find it again with no lock type |
| // no refresh is expected on a subsequent normal (no lock) find |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticReadLockAndNormalFind")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticWriteLockAndNormalFind")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticForceIncrementLockAndNormalFind")); |
| |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticReadThenWriteLockFind")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticWriteThenReadLockFind")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticForceIncrementThenReadLockFind")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticForceIncrementThenWriteLockFind")); |
| |
| // test finding and locking an object multiple times with the same lock type |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticWriteLockFindAndLock")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticReadLockFindAndLock")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticForceIncrementLockFindAndLock")); |
| |
| // test finding and lock an object then find it again with no lock type |
| // no refresh is ever expected on a subsequent normal (no lock) find |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticReadLockAndNormalFindAndLock")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticWriteLockAndNormalFindAndLock")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticForceIncrementLockAndNormalFindAndLock")); |
| |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticReadThenWriteLockFindAndLock")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticWriteThenReadLockFindAndLock")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticForceIncrementThenReadLockFindAndLock")); |
| suite.addTest(new PessimisticLockEntityRefreshTestSuite("testPessimisticForceIncrementThenWriteLockFindAndLock")); |
| } |
| return suite; |
| } |
| |
| public void testSetup() { |
| ServerSession session = JUnitTestCase.getServerSession(); |
| new AdvancedTableCreator().replaceTables(session); |
| clearCache(); |
| } |
| |
| public void testPessimisticReadLockAndNormalFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_READ, LockModeType.NONE); |
| } |
| |
| public void testPessimisticWriteLockAndNormalFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_WRITE, LockModeType.NONE); |
| } |
| |
| public void testPessimisticForceIncrementLockAndNormalFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_WRITE, LockModeType.NONE); |
| } |
| |
| public void testPessimisticReadLockFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_READ, LockModeType.PESSIMISTIC_READ); |
| } |
| |
| public void testPessimisticWriteLockFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_WRITE, LockModeType.PESSIMISTIC_WRITE); |
| } |
| |
| public void testPessimisticForceIncrementLockFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_FORCE_INCREMENT, LockModeType.PESSIMISTIC_FORCE_INCREMENT); |
| } |
| |
| public void testPessimisticReadThenWriteLockFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_READ, LockModeType.PESSIMISTIC_WRITE); |
| } |
| |
| public void testPessimisticWriteThenReadLockFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_WRITE, LockModeType.PESSIMISTIC_READ); |
| } |
| |
| public void testPessimisticForceIncrementThenReadLockFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_FORCE_INCREMENT, LockModeType.PESSIMISTIC_READ); |
| } |
| |
| public void testPessimisticForceIncrementThenWriteLockFind() { |
| doFindWithLockModes(LockModeType.PESSIMISTIC_FORCE_INCREMENT, LockModeType.PESSIMISTIC_WRITE); |
| } |
| |
| // Find-Lock tests |
| |
| public void testPessimisticReadLockAndNormalFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_READ, LockModeType.NONE); |
| } |
| |
| public void testPessimisticWriteLockAndNormalFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_WRITE, LockModeType.NONE); |
| } |
| |
| public void testPessimisticForceIncrementLockAndNormalFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_WRITE, LockModeType.NONE); |
| } |
| |
| public void testPessimisticReadLockFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_READ, LockModeType.PESSIMISTIC_READ); |
| } |
| |
| public void testPessimisticWriteLockFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_WRITE, LockModeType.PESSIMISTIC_WRITE); |
| } |
| |
| public void testPessimisticForceIncrementLockFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_FORCE_INCREMENT, LockModeType.PESSIMISTIC_FORCE_INCREMENT); |
| } |
| |
| public void testPessimisticReadThenWriteLockFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_READ, LockModeType.PESSIMISTIC_WRITE); |
| } |
| |
| public void testPessimisticWriteThenReadLockFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_WRITE, LockModeType.PESSIMISTIC_READ); |
| } |
| |
| public void testPessimisticForceIncrementThenReadLockFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_FORCE_INCREMENT, LockModeType.PESSIMISTIC_READ); |
| } |
| |
| public void testPessimisticForceIncrementThenWriteLockFindAndLock() { |
| doFindAndLockWithLockModes(LockModeType.PESSIMISTIC_FORCE_INCREMENT, LockModeType.PESSIMISTIC_WRITE); |
| } |
| |
| /** |
| * Test utility method |
| * @param lockMode1 - the lock mode for the first find() |
| * @param lockMode2 - the lock mode for the second find() |
| */ |
| public void doFindWithLockModes(LockModeType lockMode1, LockModeType lockMode2) { |
| if (!isSelectForUpateSupported()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| Address entity = new Address("Wellington St.", "Ottawa", "ON", "Canada", "K1A0A6"); |
| em.persist(entity); |
| em.flush(); |
| int entityId = entity.getID(); |
| |
| entity = em.find(Address.class, entityId, lockMode1); |
| assertNotNull("Test data: entity should not be null", entity); |
| entity.setCountry("changed"); |
| |
| Address entityRetrievedAgain = em.find(Address.class, entityId, lockMode2); |
| |
| assertNotNull("Test data: entity retrieved again should not be null", entityRetrievedAgain); |
| assertTrue("Same entity instance should be returned from find", entity == entityRetrievedAgain); |
| assertEquals("Field value is expected to be the same", "changed", entityRetrievedAgain.getCountry()); |
| assertEquals("Version field is expected to be the same", entity.getVersion(), entityRetrievedAgain.getVersion()); |
| } catch (RuntimeException ex) { |
| throw ex; |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| } |
| |
| /** |
| * Test utility method |
| * @param lockMode1 - the lock mode for the first lock() |
| * @param lockMode2 - the lock mode for the second lock() |
| */ |
| public void doFindAndLockWithLockModes(LockModeType lockMode1, LockModeType lockMode2) { |
| if (!isSelectForUpateSupported()) { |
| return; |
| } |
| EntityManager em = createEntityManager(); |
| beginTransaction(em); |
| try { |
| Address entity = new Address("Wellington St.", "Ottawa", "ON", "Canada", "K1A0A6"); |
| em.persist(entity); |
| em.flush(); |
| int entityId = entity.getID(); |
| |
| entity = em.find(Address.class, entityId); |
| em.lock(entity, lockMode1); |
| |
| assertNotNull("Test data: entity should not be null", entity); |
| entity.setCountry("changed"); |
| |
| Address entityRetrievedAgain = em.find(Address.class, entityId); |
| em.lock(entityRetrievedAgain, lockMode2); |
| |
| assertNotNull("Test data: entity retrieved again should not be null", entityRetrievedAgain); |
| assertTrue("Same entity instance should be returned from find", entity == entityRetrievedAgain); |
| assertEquals("Field value is expected to be the same", "changed", entityRetrievedAgain.getCountry()); |
| assertEquals("Version field is expected to be the same", entity.getVersion(), entityRetrievedAgain.getVersion()); |
| } catch (RuntimeException ex) { |
| throw ex; |
| } finally { |
| closeEntityManagerAndTransaction(em); |
| } |
| } |
| |
| } |