/******************************************************************************* | |
* Copyright (c) 2011, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* 11/10/2011-2.4 Guy Pelletier | |
* - 357474: Address primaryKey option from tenant discriminator column | |
******************************************************************************/ | |
package org.eclipse.persistence.mappings; | |
import org.eclipse.persistence.exceptions.DescriptorException; | |
import org.eclipse.persistence.internal.descriptors.MultitenantPrimaryKeyAccessor; | |
import org.eclipse.persistence.internal.helper.DatabaseField; | |
import org.eclipse.persistence.internal.identitymaps.CacheKey; | |
import org.eclipse.persistence.internal.queries.JoinedAttributeManager; | |
import org.eclipse.persistence.internal.sessions.AbstractRecord; | |
import org.eclipse.persistence.internal.sessions.AbstractSession; | |
import org.eclipse.persistence.internal.sessions.ChangeRecord; | |
import org.eclipse.persistence.internal.sessions.MergeManager; | |
import org.eclipse.persistence.internal.sessions.ObjectChangeSet; | |
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl; | |
import org.eclipse.persistence.mappings.foundation.AbstractColumnMapping; | |
import org.eclipse.persistence.queries.ObjectBuildingQuery; | |
import org.eclipse.persistence.sessions.Session; | |
/** | |
* <b>Purpose</b>: Maps a multitenant 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. | |
* | |
* @author Guy Pelletier | |
* @since EclipseLink 2.4 | |
*/ | |
public class MultitenantPrimaryKeyMapping extends AbstractColumnMapping { | |
private MultitenantPrimaryKeyAccessor accessor; | |
/** | |
* Constructor | |
*/ | |
public MultitenantPrimaryKeyMapping() { | |
super(); | |
isInsertable = true; | |
isUpdatable = false; | |
setIsOptional(false); | |
accessor = new MultitenantPrimaryKeyAccessor(); | |
setAttributeAccessor(accessor); | |
} | |
/** | |
* INTERNAL: | |
* Clone the attribute from the clone and assign it to the backup. | |
* | |
* This is an override from DatabaseMapping and must be implemented. | |
*/ | |
@Override | |
public void buildBackupClone(Object clone, Object backup, UnitOfWorkImpl unitOfWork) { | |
// Mapping is write only so nothing to do. | |
} | |
/** | |
* INTERNAL: | |
* Clone the attribute from the original and assign it to the clone. | |
* | |
* This is an override from DatabaseMapping and must be implemented. | |
*/ | |
@Override | |
public void buildClone(Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession) { | |
// Mapping is write only so nothing to do. | |
} | |
/** | |
* INTERNAL: | |
* Extract value from the row and set the attribute to this value in the | |
* working copy clone. | |
* In order to bypass the shared cache when in transaction a UnitOfWork must | |
* be able to populate working copies directly from the row. | |
*/ | |
@Override | |
public void buildCloneFromRow(AbstractRecord databaseRow, JoinedAttributeManager joinManager, Object clone, CacheKey sharedCacheKey, ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork, AbstractSession executionSession) { | |
// Mapping is write only so nothing to do. | |
} | |
/** | |
* INTERNAL: | |
* Compare the clone and backup clone values and return a change record if | |
* the value changed. | |
* | |
* This is an override from DatabaseMapping and must be implemented. | |
*/ | |
@Override | |
public ChangeRecord compareForChange(Object clone, Object backUp, ObjectChangeSet owner, AbstractSession session) { | |
// Mapping is write only so nothing to do. | |
return null; | |
} | |
/** | |
* INTERNAL: | |
* Compare the attributes belonging to this mapping for the objects. | |
* | |
* This is an override from DatabaseMapping and must be implemented. | |
*/ | |
@Override | |
public boolean compareObjects(Object firstObject, Object secondObject, AbstractSession session) { | |
// Mapping is write only so nothing to do. | |
return true; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
@Override | |
public Object getFieldValue(Object propertyValue, AbstractSession session) { | |
return accessor.getValue(session); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
@Override | |
public Object getObjectValue(Object fieldValue, Session session) { | |
return accessor.getValue(session); | |
} | |
/** | |
* INTERNAL: | |
* The mapping is initialized with the given session. This mapping is fully | |
* initialized after this. | |
*/ | |
@Override | |
public void initialize(AbstractSession session) throws DescriptorException { | |
super.initialize(session); | |
if (getField() == null) { | |
session.getIntegrityChecker().handleError(DescriptorException.fieldNameNotSetInMapping(this)); | |
} | |
setField(getDescriptor().buildField(getField())); | |
setFields(collectFields()); | |
// Must unwrap Struct types on WLS. | |
if (getField().getSqlType() == java.sql.Types.STRUCT) { | |
getDescriptor().setIsNativeConnectionRequired(true); | |
} | |
} | |
/** | |
* INTERNAL: | |
* Return if this mapping requires its attribute value to be cloned. | |
*/ | |
@Override | |
public boolean isCloningRequired() { | |
return false; | |
} | |
/** | |
* INTERNAL | |
*/ | |
@Override | |
public boolean isMultitenantPrimaryKeyMapping() { | |
return true; | |
} | |
/** | |
* INTERNAL: | |
*/ | |
public boolean isRelationalMapping() { | |
return true; | |
} | |
/** | |
* INTERNAL | |
* This mapping must be write only as their is no attribute to read into. | |
*/ | |
@Override | |
public boolean isWriteOnly() { | |
return true; | |
} | |
/** | |
* INTERNAL: | |
* Merge changes from the source to the target object. | |
* | |
* This is an override from DatabaseMapping and must be implemented. | |
*/ | |
@Override | |
public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) { | |
// Mapping is write only so do nothing. | |
} | |
/** | |
* INTERNAL: | |
* Merge changes from the source to the target object. This merge is only | |
* called when a changeSet for the target does not exist or the target is | |
* uninitialized | |
* | |
* This is an override from DatabaseMapping and must be implemented. | |
*/ | |
@Override | |
public void mergeIntoObject(Object target, boolean isTargetUninitialized, Object source, MergeManager mergeManager, AbstractSession targetSession) { | |
// Mapping is write only so do nothing. | |
} | |
/** | |
* INTERNAL: | |
* The context property that is used to write this mapping must be set. It | |
* is set as the attribute name (which gets set on the accessor) | |
*/ | |
public void setContextProperty(String contextProperty) { | |
setAttributeName(contextProperty); | |
} | |
/** | |
* INTERNAL: | |
* Get a value from the object and set that in the respective field of the row. | |
*/ | |
@Override | |
public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) { | |
writeValueIntoRow(row, getField(), getFieldValue(null, session)); | |
} | |
/** | |
* INTERNAL: | |
* Return the Value from the object. | |
*/ | |
@Override | |
public Object valueFromObject(Object anObject, DatabaseField field, AbstractSession session) { | |
return accessor.getValue(session); | |
} | |
/** | |
* INTERNAL: | |
* Write fields needed for insert into the template for with null values. | |
*/ | |
@Override | |
public void writeInsertFieldsIntoRow(AbstractRecord databaseRow, AbstractSession session) { | |
databaseRow.add(getField(), null); | |
} | |
/** | |
* INTERNAL: | |
*/ | |
@Override | |
protected void writeValueIntoRow(AbstractRecord row, DatabaseField field, Object fieldValue) { | |
row.add(getField(), fieldValue); | |
} | |
} |