org.eclipse.persistence.mappings.foundation.AbstractColumnMapping Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
The newest version!
/*
* Copyright (c) 1998, 2024 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
// 11/13/2009-2.0 mobrien - 294765: MapKey keyType DirectToField processing
// should return attributeClassification class in getMapKeyTargetType when
// accessor.attributeField is null in the absence of a MapKey annotation
// 11/10/2011-2.4 Guy Pelletier
// - 357474: Address primaryKey option from tenant discriminator column
// 30/05/2012-2.4 Guy Pelletier
// - 354678: Temp classloader is still being used during metadata processing
// 06/03/2013-2.5.1 Guy Pelletier
// - 402380: 3 jpa21/advanced tests failed on server with
// "java.lang.NoClassDefFoundError: org/eclipse/persistence/testing/models/jpa21/advanced/enums/Gender"
package org.eclipse.persistence.mappings.foundation;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.sessions.remote.ObjectDescriptor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.remote.DistributedSession;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Purpose: Maps an attribute or some other property to the corresponding
* database field type. The list of field types that are supported by
* EclipseLink's direct to field mapping is dependent on the relational database
* being used.
*
* @see org.eclipse.persistence.mappings.foundation.AbstractDirectMapping
* @see org.eclipse.persistence.mappings.MultitenantPrimaryKeyMapping
*
* @author Guy Pelletier
* @since TopLink/Java 1.0
*/
public abstract class AbstractColumnMapping extends DatabaseMapping {
/** DatabaseField which this mapping represents. */
protected DatabaseField field;
/** Allows user defined conversion between the object attribute value and the database value. */
protected Converter converter;
protected String converterClassName;
/** Flag to support insertable JPA setting */
protected boolean isInsertable = true;
/** Flag to support updatable JPA setting */
protected boolean isUpdatable = true;
/**
* Default constructor.
*/
protected AbstractColumnMapping() {
super();
this.setWeight(WEIGHT_DIRECT);
}
/**
* INTERNAL:
* Cascade perform delete through mappings that require the cascade.
*/
@Override
public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
// objects referenced by this mapping are not registered as they have
// no identity, this is a no-op.
}
/**
* INTERNAL:
* Cascade registerNew for Create through mappings that require the cascade.
*/
@Override
public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
// objects referenced by this mapping are not registered as they have
// no identity, this is a no-op.
}
/**
* INTERNAL:
* The mapping clones itself to create deep copy.
*/
@Override
public Object clone() {
AbstractColumnMapping clone = (AbstractColumnMapping)super.clone();
// Field must be cloned so aggregates do not share fields.
clone.setField(getField().clone());
return clone;
}
/**
* Returns the field this mapping represents.
*/
@Override
protected List collectFields() {
List databaseField = new ArrayList<>(1);
databaseField.add(field);
return databaseField;
}
/**
* INTERNAL:
* Convert all the class-name-based settings in this mapping to actual class-based settings
* This method is implemented by subclasses as necessary.
*/
@Override
public void convertClassNamesToClasses(ClassLoader classLoader){
super.convertClassNamesToClasses(classLoader);
// Field may have a type name that needs to be initialize.
if (field != null) {
field.convertClassNamesToClasses(classLoader);
}
// Convert and any Converter class names.
convertConverterClassNamesToClasses(converter, classLoader);
// Instantiate any custom converter class
if (converterClassName != null) {
Class extends Converter> converterClass;
Converter converter;
try {
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
converterClass = AccessController.doPrivileged(new PrivilegedClassForName<>(converterClassName, true, classLoader));
} catch (PrivilegedActionException exception) {
throw ValidationException.classNotFoundWhileConvertingClassNames(converterClassName, exception.getException());
}
try {
converter = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(converterClass));
} catch (PrivilegedActionException exception) {
throw ValidationException.classNotFoundWhileConvertingClassNames(converterClassName, exception.getException());
}
} else {
converterClass = PrivilegedAccessHelper.getClassForName(converterClassName, true, classLoader);
converter = PrivilegedAccessHelper.newInstanceFromClass(converterClass);
}
} catch (ClassNotFoundException exc) {
throw ValidationException.classNotFoundWhileConvertingClassNames(converterClassName, exc);
} catch (Exception e) {
// Catches IllegalAccessException and InstantiationException
throw ValidationException.classNotFoundWhileConvertingClassNames(converterClassName, e);
}
setConverter(converter);
}
}
/**
* INTERNAL:
* An object has been serialized from the server to the client.
* Replace the transient attributes of the remote value holders
* with client-side objects.
*/
@Override
public void fixObjectReferences(Object object, Map