blob: a73c128f1f77c8fd9719f9795950d335ce7a2fc4 [file] [log] [blame]
/*
* 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;
import java.io.Serializable;
import java.io.StringWriter;
import java.math.BigDecimal;
import org.eclipse.persistence.descriptors.RelationalDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
import org.eclipse.persistence.testing.tests.unitofwork.ConcurrentReadOnUpdateWithEarlyTransTest;
import org.eclipse.persistence.tools.schemaframework.TableDefinition;
/**
* <p><b>Purpose</b>: Represents the mailing address on an Employee
* <p><b>Description</b>: Held in a private 1:1 relationship from Employee
* @see ConcurrentPerson
*/
public class ConcurrentAddress implements Serializable, Cloneable {
public BigDecimal id;
public String street;
public String city;
public String province;
public String postalCode;
public String country;
//USED TO DETERMINE WHICH TEST IS RUNNING
public static int RUNNING_TEST;
//tests
public static final int NONE = Integer.MIN_VALUE;
public static final int LOCK_ON_CLONE_TEST = 55;
public static final int LOCK_ON_CLONE_DEADLOCK = 56;
public static final int READ_ON_UPDATE_EARLY_TRANS = 57;
public static boolean isForBackup = false;
public ConcurrentAddress() {
this.city = "";
this.province = "";
this.postalCode = "";
this.street = "";
this.country = "";
}
@Override
public Object clone() {
ConcurrentAddress result = new ConcurrentAddress();
result.id = this.id;
result.city = this.city;
result.province = this.province;
result.postalCode = this.postalCode;
result.street = this.street;
result.country = this.country;
return result;
}
public String getCity() {
return city;
}
public String getCountry() {
try {
if (ConcurrentRefreshOnCloneTest.lock != null) {
synchronized (ConcurrentRefreshOnCloneTest.lock) {
if (!ConcurrentRefreshOnCloneTest.waited) {
if (ConcurrentRefreshOnCloneTest.readerWaiting) {
ConcurrentRefreshOnCloneTest.lock.notifyAll();
Thread.yield();
}
// verify that we are not currently holding an active lock on the system. Which would result in a deadlock
if (((AbstractSession)ConcurrentRefreshOnCloneTest.session).getIdentityMapAccessorInstance().getIdentityMapManager().getCacheMutex().getActiveThread() !=
Thread.currentThread()) {
ConcurrentRefreshOnCloneTest.cloneWaiting = true;
ConcurrentRefreshOnCloneTest.lock.wait(30000);
ConcurrentRefreshOnCloneTest.cloneWaiting = false;
} else {
//can't lock but let's sleep to simulate a window for refresh
Thread.sleep(4000);
}
ConcurrentRefreshOnCloneTest.waited = true;
}
}
}
} catch (Exception ex) {
}
return country;
}
/**
* Return the persistent identifier of the receiver.
*/
public BigDecimal getId() {
return id;
}
public String getPostalCode() {
return postalCode;
}
public String getProvince() {
//used in the Lock on clone test
if ((ConcurrentAddress.RUNNING_TEST == ConcurrentAddress.LOCK_ON_CLONE_TEST) ||
(ConcurrentAddress.RUNNING_TEST == ConcurrentAddress.LOCK_ON_CLONE_DEADLOCK)) {
if (!isForBackup) {
synchronized (this) {
isForBackup = true; //the next call to this method will be for backup
this.notifyAll(); // let refresh update the fields
try {
this.wait(10000); //wait for refresh to update the fields
} catch (InterruptedException ex) {
}
}
} else {
isForBackup = false;
}
}
return province;
}
public String getStreet() {
return street;
}
public void setCity(String city) {
this.city = city;
}
public void setCountry(String country) {
this.country = country;
}
/**
* Set the persistent identifier of the receiver.
*/
public void setId(BigDecimal id) {
try {
if (ConcurrentAddress.RUNNING_TEST == ConcurrentAddress.READ_ON_UPDATE_EARLY_TRANS) {
if (ConcurrentReadOnUpdateWithEarlyTransTest.threadId.get().equals("Writer")) {
synchronized (ConcurrentReadOnUpdateWithEarlyTransTest.readAddress) {
ConcurrentReadOnUpdateWithEarlyTransTest.readAddress.notify(); // wake up reader.
ConcurrentReadOnUpdateWithEarlyTransTest.whosWaiting =
ConcurrentReadOnUpdateWithEarlyTransTest.WRITER;
ConcurrentReadOnUpdateWithEarlyTransTest.readAddress.wait(30000);
}
}
} else {
if (ConcurrentReadOnInsertTest.readAddress != null) {
synchronized (ConcurrentReadOnInsertTest.readAddress) {
if (ConcurrentReadOnInsertTest.depth <= 0) {
ConcurrentReadOnInsertTest.readAddress.notifyAll();
} else {
--ConcurrentReadOnInsertTest.depth;
}
}
// make an extra buffer to ensure that the read has time to run
Thread.sleep(2000);
}
}
} catch (Exception ex) {
}
this.id = id;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public void setProvince(String province) {
this.province = province;
}
public void setStreet(String street) {
this.street = street;
}
/**
* Print the address city and province.
*/
public String toString() {
StringWriter writer = new StringWriter();
writer.write("Address: ");
writer.write(this.street);
writer.write(", ");
writer.write(this.city);
writer.write(", ");
writer.write(this.province);
writer.write(", ");
writer.write(this.country);
return writer.toString();
}
public static TableDefinition tableDefinition() {
org.eclipse.persistence.tools.schemaframework.TableDefinition tabledefinition =
new org.eclipse.persistence.tools.schemaframework.TableDefinition();
// SECTION: TABLE
tabledefinition.setName("CONCURRENT_ADDRESS");
// SECTION: FIELD
org.eclipse.persistence.tools.schemaframework.FieldDefinition field =
new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
field.setName("ADDRESS_ID");
field.setTypeName("NUMERIC");
field.setSize(15);
field.setShouldAllowNull(false);
field.setIsPrimaryKey(true);
field.setUnique(false);
field.setIsIdentity(true);
tabledefinition.addField(field);
// SECTION: FIELD
org.eclipse.persistence.tools.schemaframework.FieldDefinition field1 =
new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
field1.setName("P_CODE");
field1.setTypeName("VARCHAR");
field1.setSize(20);
field1.setShouldAllowNull(true);
field1.setIsPrimaryKey(false);
field1.setUnique(false);
field1.setIsIdentity(false);
tabledefinition.addField(field1);
// SECTION: FIELD
org.eclipse.persistence.tools.schemaframework.FieldDefinition field2 =
new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
field2.setName("CITY");
field2.setTypeName("VARCHAR");
field2.setSize(80);
field2.setShouldAllowNull(true);
field2.setIsPrimaryKey(false);
field2.setUnique(false);
field2.setIsIdentity(false);
tabledefinition.addField(field2);
// SECTION: FIELD
org.eclipse.persistence.tools.schemaframework.FieldDefinition field3 =
new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
field3.setName("PROVINCE");
field3.setTypeName("VARCHAR");
field3.setSize(80);
field3.setShouldAllowNull(true);
field3.setIsPrimaryKey(false);
field3.setUnique(false);
field3.setIsIdentity(false);
tabledefinition.addField(field3);
// SECTION: FIELD
org.eclipse.persistence.tools.schemaframework.FieldDefinition field4 =
new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
field4.setName("STREET");
field4.setTypeName("VARCHAR");
field4.setSize(80);
field4.setShouldAllowNull(true);
field4.setIsPrimaryKey(false);
field4.setUnique(false);
field4.setIsIdentity(false);
tabledefinition.addField(field4);
// SECTION: FIELD
org.eclipse.persistence.tools.schemaframework.FieldDefinition field5 =
new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
field5.setName("COUNTRY");
field5.setTypeName("VARCHAR");
field5.setSize(80);
field5.setShouldAllowNull(true);
field5.setIsPrimaryKey(false);
field5.setUnique(false);
field5.setIsIdentity(false);
tabledefinition.addField(field5);
return tabledefinition;
}
public static RelationalDescriptor descriptor() {
// NOTE: weights are set on the mapping to ensure the order in which they are
// accessed by toplink for timing purposes for test ConcurrentRefreshOnCloneTest
RelationalDescriptor descriptor = new RelationalDescriptor();
descriptor.setJavaClass(ConcurrentAddress.class);
descriptor.addTableName("CONCURRENT_ADDRESS");
descriptor.addPrimaryKeyFieldName("CONCURRENT_ADDRESS.ADDRESS_ID");
// RelationalDescriptor properties.
descriptor.useFullIdentityMap();
descriptor.setIdentityMapSize(100);
descriptor.setSequenceNumberFieldName("ADDRESS_ID");
descriptor.setSequenceNumberName("ADDRESS_SEQ");
// Query manager.
descriptor.getQueryManager().checkCacheForDoesExist();
// Event manager.
// Mappings.
DirectToFieldMapping cityMapping = new DirectToFieldMapping();
cityMapping.setAttributeName("city");
cityMapping.setFieldName("CONCURRENT_ADDRESS.CITY");
cityMapping.setWeight(10);
descriptor.addMapping(cityMapping);
DirectToFieldMapping countryMapping = new DirectToFieldMapping();
countryMapping.setAttributeName("country");
countryMapping.setFieldName("CONCURRENT_ADDRESS.COUNTRY");
countryMapping.setSetMethodName("setCountry");
countryMapping.setGetMethodName("getCountry");
countryMapping.setWeight(9);
descriptor.addMapping(countryMapping);
DirectToFieldMapping idMapping = new DirectToFieldMapping();
idMapping.setAttributeName("id");
idMapping.setFieldName("CONCURRENT_ADDRESS.ADDRESS_ID");
idMapping.setSetMethodName("setId");
idMapping.setGetMethodName("getId");
idMapping.setWeight(8);
descriptor.addMapping(idMapping);
DirectToFieldMapping postalCodeMapping = new DirectToFieldMapping();
postalCodeMapping.setAttributeName("postalCode");
postalCodeMapping.setFieldName("CONCURRENT_ADDRESS.P_CODE");
postalCodeMapping.setWeight(7);
descriptor.addMapping(postalCodeMapping);
DirectToFieldMapping provinceMapping = new DirectToFieldMapping();
provinceMapping.setAttributeName("province");
provinceMapping.setFieldName("CONCURRENT_ADDRESS.PROVINCE");
provinceMapping.setSetMethodName("setProvince");
provinceMapping.setGetMethodName("getProvince");
provinceMapping.setWeight(6);
descriptor.addMapping(provinceMapping);
DirectToFieldMapping streetMapping = new DirectToFieldMapping();
streetMapping.setAttributeName("street");
streetMapping.setFieldName("CONCURRENT_ADDRESS.STREET");
streetMapping.setWeight(5);
descriptor.addMapping(streetMapping);
return descriptor;
}
}