JDBCCMRFieldBridge a bean relationship. This class only supports
relationships between entities managed by a JDBCStoreManager in the same
application.
Life-cycle:
Tied to the EntityBridge.
Multiplicity:
One for each role that entity has.
| Method from org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge Detail: |
public void addRelatedPKWaitingForMyPK(Object myPK,
Object relatedPK) {
Map relatedPKsWaitingForMyPK = getRelatedPKsWaitingForMyPK();
synchronized(relatedPKsWaitingForMyPK)
{
List relatedPKs = (List) relatedPKsWaitingForMyPK.get(myPK);
if(relatedPKs == null)
{
relatedPKs = new ArrayList(1);
relatedPKsWaitingForMyPK.put(myPK, relatedPKs);
}
relatedPKs.add(relatedPK);
}
}
|
public void addRelatedPKsWaitedForMe(EntityEnterpriseContext ctx) {
final Map relatedPKsMap = getRelatedPKsWaitingForMyPK();
synchronized(relatedPKsMap)
{
List relatedPKsWaitingForMe = (List) relatedPKsMap.get(ctx.getId());
if(relatedPKsWaitingForMe != null)
{
for(Iterator waitingPKsIter = relatedPKsWaitingForMe.iterator(); waitingPKsIter.hasNext();)
{
Object waitingPK = waitingPKsIter.next();
waitingPKsIter.remove();
if(isForeignKeyValid(waitingPK))
{
createRelationLinks(ctx, waitingPK);
}
}
}
}
}
Establishes relationships with related entities waited for passed in context
to be created. |
public void addRelation(EntityEnterpriseContext myCtx,
Object fk) {
addRelation(myCtx, fk, true);
relationManager.addRelation(this, myCtx.getId(), relatedCMRField, fk);
}
Adds the foreign key to the set of related ids, and updates any foreign key fields. |
public boolean allFkFieldsMappedToPkFields() {
return allFKFieldsMappedToPKFields;
}
Returns true if all FK fields are mapped to PK fields |
public void cascadeDelete(EntityEnterpriseContext ctx,
List oldValues) throws RemoveException, RemoteException {
cascadeDeleteStrategy.cascadeDelete(ctx, oldValues);
}
|
public void createRelationLinks(EntityEnterpriseContext myCtx,
Object relatedId) {
createRelationLinks(myCtx, relatedId, true);
}
Creates the relation links between the instance associated with the
context and the related instance (just the id is passed in).
This method calls a.addRelation(b) and b.addRelation(a) |
public void createRelationLinks(EntityEnterpriseContext myCtx,
Object relatedId,
boolean updateForeignKey) {
if(isReadOnly())
{
throw new EJBException("Field is read-only: " + getFieldName());
}
// If my multiplicity is one, then we need to free the new related context
// from its old relationship.
Transaction tx = getTransaction();
if(metadata.isMultiplicityOne())
{
Object oldRelatedId = relatedCMRField.invokeGetRelatedId(tx, relatedId);
if(oldRelatedId != null)
{
invokeRemoveRelation(tx, oldRelatedId, relatedId);
relatedCMRField.invokeRemoveRelation(tx, relatedId, oldRelatedId);
}
}
addRelation(myCtx, relatedId, updateForeignKey);
relatedCMRField.invokeAddRelation(tx, relatedId, myCtx.getId());
}
|
public void destroyRelationLinks(EntityEnterpriseContext myCtx,
Object relatedId) {
destroyRelationLinks(myCtx, relatedId, true);
}
Destroys the relation links between the instance associated with the
context and the related instance (just the id is passed in).
This method calls a.removeRelation(b) and b.removeRelation(a) |
public void destroyRelationLinks(EntityEnterpriseContext myCtx,
Object relatedId,
boolean updateValueCollection) {
destroyRelationLinks(myCtx, relatedId, updateValueCollection, true);
}
Destroys the relation links between the instance associated with the
context and the related instance (just the id is passed in).
This method calls a.removeRelation(b) and b.removeRelation(a)
If updateValueCollection is false, the related id collection is not
updated. This form is only used by the RelationSet iterator. |
public void destroyRelationLinks(EntityEnterpriseContext myCtx,
Object relatedId,
boolean updateValueCollection,
boolean updateForeignKey) {
if(isReadOnly())
{
throw new EJBException("Field is read-only: " + getFieldName());
}
removeRelation(myCtx, relatedId, updateValueCollection, updateForeignKey);
relatedCMRField.invokeRemoveRelation(getTransaction(), relatedId, myCtx.getId());
}
|
public DataSource getDataSource() {
return dataSource;
}
Gets the datasource of the relation table if relevent. |
public JDBCAbstractEntityBridge getEntity() {
return entity;
}
Gets bridge for this entity. |
public String getFieldName() {
return metadata.getCMRFieldName();
}
Gets the name of this field. |
public JDBCFieldBridge[] getForeignKeyFields() {
return foreignKeyFields;
}
Gets the foreign key fields of this entity (i.e., related entities pk fields) |
public Object getInstanceValue(EntityEnterpriseContext myCtx) {
load(myCtx);
FieldState fieldState = getFieldState(myCtx);
if(isCollectionValued())
{
return fieldState.getRelationSet();
}
// only return one
try
{
List value = fieldState.getValue();
if(!value.isEmpty())
{
Object fk = value.get(0);
return getRelatedEntityByFK(fk);
}
else if(foreignKeyFields != null)
{
// for those completely mapped to CMP fields and created in this current tx !!!
Object relatedId = getRelatedIdFromContext(myCtx);
if(relatedId != null)
{
return getRelatedEntityByFK(relatedId);
}
}
return null;
}
catch(EJBException e)
{
throw e;
}
catch(Exception e)
{
throw new EJBException(e);
}
}
Gets the value of the cmr field for the instance associated with
the context. |
public JDBCStoreManager getJDBCStoreManager() {
return manager;
}
Gets the manager of this entity. |
public JDBCType getJDBCType() {
return jdbcType;
}
|
public JDBCEntityPersistenceStore getManager() {
return manager;
}
|
public JDBCRelationshipRoleMetaData getMetaData() {
return metadata;
}
Gets the metadata of the relationship role that this field represents. |
public String getQualifiedTableName() {
return qualifiedTableName;
}
Gets the name of the relation table if relevent. |
public JDBCReadAheadMetaData getReadAhead() {
return metadata.getReadAhead();
}
Gets the read ahead meta data. |
public JDBCAbstractCMRFieldBridge getRelatedCMRField() {
return relatedCMRField;
}
The related entity's cmr field for this relationship. |
public EntityBridge getRelatedEntity() {
return relatedEntity;
}
|
public EJBLocalObject getRelatedEntityByFK(Object fk) {
EJBLocalObject relatedLocalObject = null;
final EntityContainer relatedContainer = getRelatedContainer();
if(hasFKFieldsMappedToCMPFields
&& relatedManager.getReadAheadCache().getPreloadDataMap(fk, false) == null // not in preload cache
)
{
EJBLocalHome relatedHome = relatedContainer.getLocalProxyFactory().getEJBLocalHome();
try
{
relatedLocalObject = (EJBLocalObject) relatedFindByPrimaryKey.invoke(relatedHome, new Object[]{fk});
}
catch(Exception ignore)
{
// no such entity. it is ok to ignore
}
}
else
{
relatedLocalObject = relatedContainer.getLocalProxyFactory().getEntityEJBLocalObject(fk);
}
return relatedLocalObject;
}
Returns related entity's local interface.
If there are foreign key fields mapped to CMP fields, existence of related entity is checked
with findByPrimaryKey and if, in this case, related instance is not found, null is returned.
If foreign key fields mapped to its own columns then existence of related entity is not checked
and just its local object is returned. |
public Object getRelatedId(EntityEnterpriseContext myCtx) {
if(isCollectionValued())
{
throw new EJBException("getRelatedId may only be called on a cmr-field with a multiplicity of one.");
}
load(myCtx);
List value = getFieldState(myCtx).getValue();
return value.isEmpty() ? null : value.get(0);
}
Get the related entity's id. This only works on single valued cmr fields. |
public Object getRelatedIdFromContext(EntityEnterpriseContext ctx) {
Object relatedId = null;
Object fkFieldValue;
for(int i = 0; i < foreignKeyFields.length; ++i)
{
JDBCCMP2xFieldBridge fkField = foreignKeyFields[i];
fkFieldValue = fkField.getInstanceValue(ctx);
if(fkFieldValue == null)
{
return null;
}
JDBCCMP2xFieldBridge relatedPKField = (JDBCCMP2xFieldBridge) relatedPKFieldsByMyFKFields.get(fkField);
relatedId = relatedPKField.setPrimaryKeyValue(relatedId, fkFieldValue);
}
return relatedId;
}
Creates a new instance of related id based on foreign key value in the context. |
public final LocalProxyFactory getRelatedInvoker() {
return getRelatedContainer().getLocalProxyFactory();
}
The related entity's local container invoker. |
public JDBCEntityBridge getRelatedJDBCEntity() {
return relatedEntity;
}
|
public final Class getRelatedLocalInterface() {
return getRelatedContainer().getLocalClass();
}
The related entity's local home interface. |
public JDBCStoreManager getRelatedManager() {
return relatedManager;
}
|
public JDBCCMRFieldBridge.RelationDataManager getRelationDataManager() {
return relationManager;
}
|
public JDBCRelationMetaData getRelationMetaData() {
return metadata.getRelationMetaData();
}
Gets the relation metadata. |
public JDBCFieldBridge[] getTableKeyFields() {
return tableKeyFields;
}
Gets the key fields that this entity maintains in the relation table. |
public String getTableName() {
return tableName;
}
|
public Object getValue(EntityEnterpriseContext ctx) {
// no user checks yet, but this is where they would go
return getInstanceValue(ctx);
}
|
public boolean hasFKFieldsMappedToCMPFields() {
return hasFKFieldsMappedToCMPFields;
}
|
public boolean hasForeignKey() {
return foreignKeyFields != null;
}
Does this cmr field have foreign keys. |
public void initInstance(EntityEnterpriseContext ctx) {
// mark this field as loaded
getFieldState(ctx).loadRelations(Collections.EMPTY_SET);
if(foreignKeyFields == null)
{
return;
}
for(int i = 0; i < foreignKeyFields.length; ++i)
{
JDBCCMP2xFieldBridge foreignKeyField = foreignKeyFields[i];
if(!foreignKeyField.isFKFieldMappedToCMPField())
{
foreignKeyField.setInstanceValue(ctx, null);
}
}
}
Initialized the foreign key fields. |
public boolean invalidateCache(EntityEnterpriseContext ctx) {
JDBCContext jdbcCtx = (JDBCContext) ctx.getPersistenceContext();
FieldState fieldState = (FieldState) jdbcCtx.getFieldState(jdbcContextIndex);
return fieldState == null ? false : fieldState.isChanged();
}
|
public boolean isBatchCascadeDelete() {
return (cascadeDeleteStrategy instanceof CascadeDeleteStrategy.BatchCascadeDeleteStrategy);
}
|
public boolean isCMPField() {
return false;
}
|
public boolean isCollectionValued() {
return metadata.getRelatedRole().isMultiplicityMany();
}
Is this a collection valued field. |
public boolean isDirty(EntityEnterpriseContext ctx) {
return foreignKeyFields == null ? relationManager.isDirty() : false;
}
This method is never called.
In case of a CMR with foreign key fields, only the foreign key fields are asked for the dirty state. |
public boolean isForeignKeyValid(Object fk) {
boolean valid;
if(relatedManager.getReadAheadCache().getPreloadDataMap(fk, false) != null)
{
valid = true;
}
else
{
EJBLocalHome relatedHome = getRelatedContainer().getLocalProxyFactory().getEJBLocalHome();
try
{
relatedFindByPrimaryKey.invoke(relatedHome, new Object[]{fk});
valid = true;
}
catch(Exception ignore)
{
// no such entity. it is ok to ignore
valid = false;
}
}
return valid;
}
This method is called only for CMR fields with foreign key fields mapped to CMP fields
to check the validity of the foreign key value. |
public boolean isLoaded(EntityEnterpriseContext ctx) {
return getFieldState(ctx).isLoaded;
}
|
public boolean isPrimaryKeyMember() {
return false;
}
|
public boolean isReadOnly() {
return getRelationMetaData().isReadOnly();
}
|
public boolean isReadTimedOut(EntityEnterpriseContext ctx) {
// if we are read/write then we are always timed out
if(!isReadOnly())
{
return true;
}
// if read-time-out is -1 then we never time out.
if(getRelationMetaData().getReadTimeOut() == -1)
{
return false;
}
long readInterval = System.currentTimeMillis() - getFieldState(ctx).getLastRead();
return readInterval > getRelationMetaData().getReadTimeOut();
}
Had the read time expired? |
public boolean isSingleValued() {
return metadata.getRelatedRole().isMultiplicityOne();
}
Is this a single valued field. |
public void load(EntityEnterpriseContext myCtx,
Collection values) {
// did we get more then one value for a single valued field
if(isSingleValued() && values.size() > 1)
{
throw new EJBException("Data contains multiple values, but this cmr field is single valued: " + values);
}
// add the new values
FieldState fieldState = getFieldState(myCtx);
fieldState.loadRelations(values);
// set the foreign key, if we have one.
if(hasForeignKey())
{
// update the states and locked values of FK fields
if(!values.isEmpty())
{
Object loadedValue = values.iterator().next();
for(int i = 0; i < foreignKeyFields.length; ++i)
{
JDBCCMP2xFieldBridge fkField = foreignKeyFields[i];
Object fieldValue = fkField.getPrimaryKeyValue(loadedValue);
fkField.updateState(myCtx, fieldValue);
}
}
// set the real FK value
List realValue = fieldState.getValue();
Object fk = realValue.isEmpty() ? null : realValue.get(0);
setForeignKey(myCtx, fk);
}
JDBCEntityBridge.setCreated(myCtx);
}
|
public int loadArgumentResults(ResultSet rs,
int parameterIndex,
Object[] fkRef) {
if(foreignKeyFields == null)
{
return parameterIndex;
}
boolean fkIsNull = false;
// value of this field, will be filled in below
Object[] argumentRef = new Object[1];
for(int i = 0; i < foreignKeyFields.length; ++i)
{
JDBCCMPFieldBridge field = foreignKeyFields[i];
parameterIndex = field.loadArgumentResults(rs, parameterIndex, argumentRef);
if(fkIsNull)
{
continue;
}
if(field.getPrimaryKeyField() != null)
{
// if there is a null field among FK fields, the whole FK field is considered null.
// NOTE: don't throw exception in this case, it's ok if FK is partly mapped to a PK
// NOTE2: we still need to iterate through foreign key fields and 'load' them to
// return correct parameterIndex.
if(argumentRef[0] == null)
{
fkRef[0] = null;
fkIsNull = true;
}
else
{
// if we don't have a pk object yet create one
if(fkRef[0] == null)
{
fkRef[0] = relatedEntity.createPrimaryKeyInstance();
}
try
{
// Set this field's value into the primary key object.
field.getPrimaryKeyField().set(fkRef[0], argumentRef[0]);
}
catch(Exception e)
{
// Non recoverable internal exception
throw new EJBException("Internal error setting foreign-key field " + getFieldName(), e);
}
}
}
else
{
// This field is the primary key, so no extraction is necessary.
fkRef[0] = argumentRef[0];
}
}
return parameterIndex;
}
|
public int loadInstanceResults(ResultSet rs,
int parameterIndex,
EntityEnterpriseContext ctx) {
if(!hasForeignKey())
{
return parameterIndex;
}
// load the value from the database
Object[] ref = new Object[1];
parameterIndex = loadArgumentResults(rs, parameterIndex, ref);
// only actually set the value if the state is not already loaded
FieldState fieldState = getFieldState(ctx);
if(!fieldState.isLoaded())
{
if(ref[0] != null)
{
load(ctx, Collections.singleton(ref[0]));
}
else
{
load(ctx, Collections.EMPTY_SET);
}
}
return parameterIndex;
}
|
public boolean removeFromRelations(EntityEnterpriseContext ctx,
Object[] oldRelationsRef) {
load(ctx);
FieldState fieldState = getFieldState(ctx);
List value = fieldState.getValue();
boolean removed = false;
if(!value.isEmpty())
{
if(hasFKFieldsMappedToCMPFields)
{
if(isForeignKeyValid(value.get(0)))
{
cascadeDeleteStrategy.removedIds(ctx, oldRelationsRef, value);
removed = true;
}
}
else
{
cascadeDeleteStrategy.removedIds(ctx, oldRelationsRef, value);
removed = true;
}
}
return removed;
}
|
public void removeRelatedPKWaitingForMyPK(Object myPK,
Object relatedPK) {
final Map relatedPKMap = getRelatedPKsWaitingForMyPK();
synchronized(relatedPKMap)
{
List relatedPKs = (List) relatedPKMap.get(myPK);
if(relatedPKs != null)
{
relatedPKs.remove(relatedPK);
}
}
}
|
public void removeRelation(EntityEnterpriseContext myCtx,
Object fk) {
removeRelation(myCtx, fk, true, true);
relationManager.removeRelation(this, myCtx.getId(), relatedCMRField, fk);
}
Removes the foreign key to the set of related ids, and updates any foreign key fields. |
public void resetPersistenceContext(EntityEnterpriseContext ctx) {
// only resetStats if the read has timed out
if(!isReadTimedOut(ctx))
{
return;
}
// clear the field state
JDBCContext jdbcCtx = (JDBCContext) ctx.getPersistenceContext();
// invalidate current field state
/*
FieldState currentFieldState = (FieldState) jdbcCtx.getFieldState(jdbcContextIndex);
if(currentFieldState != null)
currentFieldState.invalidate();
*/
jdbcCtx.setFieldState(jdbcContextIndex, null);
if(foreignKeyFields == null)
{
return;
}
for(int i = 0; i < foreignKeyFields.length; ++i)
{
JDBCCMP2xFieldBridge foreignKeyField = foreignKeyFields[i];
if(!foreignKeyField.isFKFieldMappedToCMPField())
{
foreignKeyField.resetPersistenceContext(ctx);
}
}
}
resets the persistence context of the foreign key fields |
public void resolveRelationship() throws DeploymentException {
//
// Set handles to the related entity's container, cache,
// manager, and invoker
//
// Related Entity Name
String relatedEntityName = metadata.getRelatedRole().getEntity().getName();
// Related Entity
Catalog catalog = (Catalog) manager.getApplicationData("CATALOG");
relatedEntity = (JDBCEntityBridge) catalog.getEntityByEJBName(relatedEntityName);
if(relatedEntity == null)
{
throw new DeploymentException("Related entity not found: " +
"entity=" +
entity.getEntityName() +
", " +
"cmrField=" +
getFieldName() +
", " +
"relatedEntity=" + relatedEntityName);
}
// Related CMR Field
JDBCCMRFieldBridge[] cmrFields = (JDBCCMRFieldBridge[]) relatedEntity.getCMRFields();
for(int i = 0; i < cmrFields.length; ++i)
{
JDBCCMRFieldBridge cmrField = cmrFields[i];
if(metadata.getRelatedRole() == cmrField.getMetaData())
{
relatedCMRField = cmrField;
break;
}
}
// if we didn't find the related CMR field throw an exception
// with a detailed message
if(relatedCMRField == null)
{
String message = "Related CMR field not found in " +
relatedEntity.getEntityName() + " for relationship from";
message += entity.getEntityName() + ".";
if(getFieldName() != null)
{
message += getFieldName();
}
else
{
message += "< no-field >";
}
message += " to ";
message += relatedEntityName + ".";
if(metadata.getRelatedRole().getCMRFieldName() != null)
{
message += metadata.getRelatedRole().getCMRFieldName();
}
else
{
message += "< no-field >";
}
throw new DeploymentException(message);
}
// Related Manager
relatedManager = (JDBCStoreManager) relatedEntity.getManager();
// Related Container
EntityContainer relatedContainer = relatedManager.getContainer();
this.relatedContainerRef = new WeakReference(relatedContainer);
// related findByPrimaryKey
Class homeClass = (relatedContainer.getLocalHomeClass() != null ?
relatedContainer.getLocalHomeClass() : relatedContainer.getHomeClass());
try
{
relatedFindByPrimaryKey =
homeClass.getMethod("findByPrimaryKey", new Class[]{relatedEntity.getPrimaryKeyClass()});
}
catch(Exception e)
{
throw new DeploymentException("findByPrimaryKey(" +
relatedEntity.getPrimaryKeyClass().getName()
+ " pk) was not found in " + homeClass.getName());
}
//
// Initialize the key fields
//
if(metadata.getRelationMetaData().isTableMappingStyle())
{
// initialize relation table key fields
Collection tableKeys = metadata.getKeyFields();
List keyFieldsList = new ArrayList(tableKeys.size());
// first phase is to create fk fields
Map pkFieldsToFKFields = new HashMap(tableKeys.size());
for(Iterator i = tableKeys.iterator(); i.hasNext();)
{
JDBCCMPFieldMetaData cmpFieldMetaData = (JDBCCMPFieldMetaData) i.next();
FieldBridge pkField = entity.getFieldByName(cmpFieldMetaData.getFieldName());
if(pkField == null)
{
throw new DeploymentException("Primary key not found for key-field " + cmpFieldMetaData.getFieldName());
}
pkFieldsToFKFields.put(pkField, new JDBCCMP2xFieldBridge(manager, cmpFieldMetaData));
}
// second step is to order fk fields to match the order of pk fields
JDBCFieldBridge[] pkFields = entity.getPrimaryKeyFields();
for(int i = 0; i < pkFields.length; ++i)
{
Object fkField = pkFieldsToFKFields.get(pkFields[i]);
if(fkField == null)
{
throw new DeploymentException("Primary key " + pkFields[i].getFieldName() + " is not mapped.");
}
keyFieldsList.add(fkField);
}
tableKeyFields = (JDBCCMP2xFieldBridge[]) keyFieldsList.toArray(
new JDBCCMP2xFieldBridge[keyFieldsList.size()]);
dataSource = metadata.getRelationMetaData().getDataSource();
}
else
{
initializeForeignKeyFields();
dataSource = hasForeignKey() ? entity.getDataSource() : relatedEntity.getDataSource();
}
// Fix table name
//
// This code doesn't work here... The problem each side will generate
// the table name and this will only work for simple generation.
qualifiedTableName = SQLUtil.fixTableName(metadata.getRelationMetaData().getDefaultTableName(), dataSource);
tableName = SQLUtil.getTableNameWithoutSchema(qualifiedTableName);
relationManager = relatedCMRField.initRelationManager(this);
}
|
public void scheduleChildrenForBatchCascadeDelete(EntityEnterpriseContext ctx) {
load(ctx);
FieldState fieldState = getFieldState(ctx);
List value = fieldState.getValue();
if(!value.isEmpty())
{
Transaction tx = getTransaction();
for(int i = 0; i < value.size(); ++i)
{
relatedCMRField.invokeScheduleForBatchCascadeDelete(tx, value.get(i));
}
}
}
Schedules children for batch cascade delete. |
public void scheduleChildrenForCascadeDelete(EntityEnterpriseContext ctx) {
load(ctx);
FieldState fieldState = getFieldState(ctx);
List value = fieldState.getValue();
if(!value.isEmpty())
{
Transaction tx = getTransaction();
for(int i = 0; i < value.size(); ++i)
{
relatedCMRField.invokeScheduleForCascadeDelete(tx, value.get(i));
}
}
}
Schedules children for cascade delete. |
public void setClean(EntityEnterpriseContext ctx) {
throw new UnsupportedOperationException();
}
This method is never called.
In case of a CMR
- with foreign key fields, the foreign key fields are cleaned when necessary according to CMP fields'
behaviour.
- from m:m relationship, added/removed key pairs are cleared in application tx data map on sync. |
public void setForeignKey(EntityEnterpriseContext myCtx,
Object fk) {
if(!hasForeignKey())
{
throw new EJBException(getFieldName() + " CMR field does not have a foreign key to set.");
}
for(int i = 0; i < foreignKeyFields.length; ++i)
{
JDBCCMP2xFieldBridge fkField = foreignKeyFields[i];
Object fieldValue = fkField.getPrimaryKeyValue(fk);
fkField.setInstanceValue(myCtx, fieldValue);
}
}
Sets the foreign key field value. |
public int setInstanceParameters(PreparedStatement ps,
int parameterIndex,
EntityEnterpriseContext ctx) {
if(foreignKeyFields == null)
{
return parameterIndex;
}
List value = getFieldState(ctx).getValue();
Object fk = (value.isEmpty() ? null : value.get(0));
for(int i = 0; i < foreignKeyFields.length; ++i)
{
parameterIndex = foreignKeyFields[i].setPrimaryKeyParameters(ps, parameterIndex, fk);
}
return parameterIndex;
}
|
public void setInstanceValue(EntityEnterpriseContext myCtx,
Object newValue) {
// validate new value first
List newPks;
if(newValue instanceof Collection)
{
Collection col = (Collection) newValue;
if(!col.isEmpty())
{
newPks = new ArrayList(col.size());
for(Iterator iter = col.iterator(); iter.hasNext();)
{
Object localObject = iter.next();
if(localObject != null)
{
Object relatedId = getRelatedPrimaryKey(localObject);
// check whether new value modifies the primary key if there are FK fields mapped to PK fields
if(relatedPKFieldsByMyPKFields.size() > 0)
{
checkSetForeignKey(myCtx, relatedId);
}
newPks.add(relatedId);
}
}
}
else
{
newPks = Collections.EMPTY_LIST;
}
}
else
{
if(newValue != null)
{
newPks = Collections.singletonList(getRelatedPrimaryKey(newValue));
}
else
{
newPks = Collections.EMPTY_LIST;
}
}
// load the current value
load(myCtx);
FieldState fieldState = getFieldState(myCtx);
// is this just setting our own relation set back
if(newValue == fieldState.getRelationSet())
{
return;
}
try
{
// Remove old value(s)
List value = fieldState.getValue();
if(!value.isEmpty())
{
Object[] curPks = value.toArray(new Object[value.size()]);
for(int i = 0; i < curPks.length; ++i)
{
destroyRelationLinks(myCtx, curPks[i]);
}
}
// Add new value(s)
for(int i = 0; i < newPks.size(); ++i)
{
createRelationLinks(myCtx, newPks.get(i));
}
}
catch(RuntimeException e)
{
throw e;
}
catch(Exception e)
{
throw new EJBException(e);
}
}
Sets the value of the cmr field for the instance associated with
the context. |
public void setValue(EntityEnterpriseContext ctx,
Object value) {
if(isReadOnly())
{
throw new EJBException("Field is read-only: fieldName=" + getFieldName());
}
if(!JDBCEntityBridge.isEjbCreateDone(ctx))
{
throw new IllegalStateException("A CMR field cannot be set " +
"in ejbCreate; this should be done in the ejbPostCreate " +
"method instead [EJB 2.0 Spec. 10.5.2].");
}
if(isCollectionValued() && value == null)
{
throw new IllegalArgumentException("null cannot be assigned to a " +
"collection-valued cmr-field [EJB 2.0 Spec. 10.3.8].");
}
/*
if(allFKFieldsMappedToPKFields)
{
throw new IllegalStateException(
"Can't modify relationship: CMR field "
+ entity.getEntityName() + "." + getFieldName()
+ " has foreign key fields mapped to the primary key columns."
+ " Primary key may only be set once in ejbCreate [EJB 2.0 Spec. 10.3.5].");
}
*/
setInstanceValue(ctx, value);
}
|
public void start() throws DeploymentException {
cascadeDeleteStrategy = CascadeDeleteStrategy.getCascadeDeleteStrategy(this);
}
The third phase of deployment. The method is called when relationships are already resolved. |
public String toString() {
return entity.getEntityName() + '." + getFieldName();
}
|