| /* |
| * Copyright (c) 2011, 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: |
| // tware - test for bug 262157 |
| package org.eclipse.persistence.testing.tests.simultaneous; |
| |
| import java.math.BigDecimal; |
| |
| import org.eclipse.persistence.testing.framework.AutoVerifyTestCase; |
| import org.eclipse.persistence.testing.framework.TestErrorException; |
| import org.eclipse.persistence.testing.tests.unitofwork.ConcurrentLargeProject; |
| import org.eclipse.persistence.testing.tests.unitofwork.ConcurrentPerson; |
| |
| import org.eclipse.persistence.expressions.ExpressionBuilder; |
| import org.eclipse.persistence.sessions.UnitOfWork; |
| /** |
| * Test for Bug 262157 |
| * This test tests to ensure no dealock occurs in the following scenario |
| * There is a bidirectional realtionship between an object (A) without inheritance and an object (B) with inheritance with a superclass (C) |
| * A eagerly maps to C and B eagerly maps to A |
| * If the mappings are setup so that A1 maps to B1 and B1 maps to A1, ensure no deadlock will occur |
| * This test starts a thread that reads the A and pauses the build after it has acquired its locks. It then starts |
| * a thread that reads B and tests to ensure both threads run to completion |
| * @author tware |
| * |
| */ |
| public class ConcurrentReadOneToOneInheritanceTest extends AutoVerifyTestCase{ |
| |
| protected BigDecimal personId = null; |
| protected BigDecimal projectId = null; |
| protected ConcurrentPerson person = null; |
| |
| protected boolean deadlockDetected = false; |
| |
| @Override |
| public void setup(){ |
| deadlockDetected = false; |
| UnitOfWork uow = getSession().acquireUnitOfWork(); |
| person = new ConcurrentPerson(); |
| person.name = "Wenger"; |
| ConcurrentLargeProject project = new ConcurrentLargeProject(); |
| project.setName("Football"); |
| person.setHobby(project); |
| project.setSupervisor(person); |
| uow.registerObject(person); |
| uow.registerObject(project); |
| uow.commit(); |
| uow.release(); |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| personId = person.id; |
| projectId = project.getId(); |
| } |
| |
| @Override |
| public void test(){ |
| ConcurrentPerson.RUNNING_TEST = ConcurrentPerson.ONE_TO_ONE_INHERITANCE; |
| Thread thread1 = new Thread(new PersonReader(getSession().acquireUnitOfWork(), personId)); |
| Thread thread2 = new Thread(new LargeProjectReader(getSession().acquireUnitOfWork(), projectId)); |
| thread1.start(); |
| thread2.start(); |
| try { |
| thread1.join(30000); |
| if (thread1.isAlive()){ |
| try{ |
| thread1.interrupt(); |
| thread2.interrupt(); |
| }catch (Exception e) { |
| } |
| deadlockDetected = true; |
| } |
| } catch (InterruptedException ex) { |
| |
| } |
| } |
| |
| @Override |
| public void verify(){ |
| if (deadlockDetected){ |
| throw new TestErrorException("Deadlock detected when reading a bidirectional 1-1 with Inheritance."); |
| } |
| } |
| |
| @Override |
| public void reset(){ |
| ConcurrentPerson.RUNNING_TEST = ConcurrentPerson.NONE; |
| UnitOfWork uow = getSession().acquireUnitOfWork(); |
| uow.deleteObject(person.getHobby()); |
| uow.deleteObject(person); |
| uow.commit(); |
| getSession().getIdentityMapAccessor().initializeAllIdentityMaps(); |
| } |
| |
| public class PersonReader implements Runnable{ |
| private UnitOfWork uow; |
| private BigDecimal id; |
| |
| public PersonReader(UnitOfWork uow, BigDecimal id){ |
| this.uow = uow; |
| this.id = id; |
| } |
| |
| @Override |
| public void run(){ |
| uow.readObject(ConcurrentPerson.class, (new ExpressionBuilder()).get("id").equal(id)); |
| } |
| } |
| |
| public class LargeProjectReader implements Runnable{ |
| private UnitOfWork uow; |
| private BigDecimal id; |
| |
| public LargeProjectReader(UnitOfWork uow, BigDecimal id){ |
| this.uow = uow; |
| this.id = id; |
| } |
| |
| @Override |
| public void run(){ |
| uow.readObject(ConcurrentLargeProject.class, (new ExpressionBuilder()).get("id").equal(id)); |
| } |
| } |
| } |