use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.
the class RelationshipManagerImpl method checkConsistency.
/* (non-Javadoc)
* @see org.datanucleus.state.RelationshipManager#checkConsistency()
*/
public void checkConsistency() {
Iterator iter = fieldChanges.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<Integer, List<RelationChange>> entry = (Map.Entry) iter.next();
int fieldNumber = entry.getKey().intValue();
List<RelationChange> changes = entry.getValue();
AbstractMemberMetaData mmd = ownerOP.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
ClassLoaderResolver clr = ec.getClassLoaderResolver();
RelationType relationType = mmd.getRelationType(clr);
if (relationType == RelationType.ONE_TO_ONE_BI) {
// 1-1 bidirectional
checkOneToOneBidirectionalRelation(mmd, clr, ec, changes);
} else if (relationType == RelationType.MANY_TO_ONE_BI) {
// N-1 bidirectional
checkManyToOneBidirectionalRelation(mmd, clr, ec, changes);
} else if (relationType == RelationType.ONE_TO_MANY_BI) {
// 1-N bidirectional
checkOneToManyBidirectionalRelation(mmd, clr, ec, changes);
} else if (relationType == RelationType.MANY_TO_MANY_BI) {
// M-N bidirectional
checkManyToManyBidirectionalRelation(mmd, clr, ec, changes);
}
}
}
use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.
the class StateManagerImpl method replaceField.
/**
* Method to change the value of a field in the PC object.
* Adds on handling for embedded fields to the superclass handler.
* @param pc The PC object
* @param fieldNumber Number of field
* @param value The new value of the field
* @param makeDirty Whether to make the field dirty while replacing its value (in embedded owners)
*/
protected void replaceField(Persistable pc, int fieldNumber, Object value, boolean makeDirty) {
List<EmbeddedOwnerRelation> embeddedOwners = myEC.getOwnerInformationForEmbedded(this);
if (embeddedOwners != null) {
// We do this before we actually change the object so we can compare with the old value
for (EmbeddedOwnerRelation ownerRel : embeddedOwners) {
StateManagerImpl ownerOP = (StateManagerImpl) ownerRel.getOwnerOP();
AbstractMemberMetaData ownerMmd = ownerOP.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(ownerRel.getOwnerFieldNum());
if (ownerMmd.getCollection() != null) {
// PC Object embedded in collection
Object ownerField = ownerOP.provideField(ownerRel.getOwnerFieldNum());
if (ownerField instanceof SCOCollection) {
((SCOCollection) ownerField).updateEmbeddedElement(myPC, fieldNumber, value, makeDirty);
}
if ((ownerOP.flags & FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER) == 0) {
// Update the owner when one of our fields have changed, EXCEPT when they have just notified us of our owner field!
if (makeDirty) {
ownerOP.makeDirty(ownerRel.getOwnerFieldNum());
}
}
} else if (ownerMmd.getMap() != null) {
// PC Object embedded in map
Object ownerField = ownerOP.provideField(ownerRel.getOwnerFieldNum());
if (ownerField instanceof SCOMap) {
if (objectType == ObjectProvider.EMBEDDED_MAP_KEY_PC) {
((SCOMap) ownerField).updateEmbeddedKey(myPC, fieldNumber, value, makeDirty);
}
if (objectType == ObjectProvider.EMBEDDED_MAP_VALUE_PC) {
((SCOMap) ownerField).updateEmbeddedValue(myPC, fieldNumber, value, makeDirty);
}
}
if ((ownerOP.flags & FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER) == 0) {
// Update the owner when one of our fields have changed, EXCEPT when they have just notified us of our owner field!
if (makeDirty) {
ownerOP.makeDirty(ownerRel.getOwnerFieldNum());
}
}
} else {
// PC Object embedded in PC object
if ((ownerOP.flags & FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER) == 0) {
// Update the owner when one of our fields have changed, EXCEPT when they have just notified us of our owner field!
if (makeDirty) {
ownerOP.replaceFieldMakeDirty(ownerRel.getOwnerFieldNum(), pc);
} else {
ownerOP.replaceField(ownerRel.getOwnerFieldNum(), pc);
}
}
}
}
}
// TODO Why don't we mark as dirty if non-tx ? Maybe need P_NONTRANS_DIRTY
if (embeddedOwners == null && makeDirty && !myLC.isDeleted() && myEC.getTransaction().isActive()) {
// Mark dirty (if not being deleted)
boolean wasDirty = preWriteField(fieldNumber);
replaceField(pc, fieldNumber, value);
postWriteField(wasDirty);
} else {
replaceField(pc, fieldNumber, value);
}
}
use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.
the class StateManagerImpl method updateOwnerFieldInEmbeddedField.
/**
* Method to update the "owner-field" in an embedded object with the owner object.
* TODO Likely this should be moved into a replaceField method, or maybe Managed Relationships.
* @param fieldNumber The field number
* @param value The value to initialise the wrapper with (if any)
*/
public void updateOwnerFieldInEmbeddedField(int fieldNumber, Object value) {
if (value != null) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
RelationType relationType = mmd.getRelationType(myEC.getClassLoaderResolver());
if (RelationType.isRelationSingleValued(relationType) && mmd.getEmbeddedMetaData() != null && mmd.getEmbeddedMetaData().getOwnerMember() != null) {
// Embedded field, so assign the embedded/serialised object "owner-field" if specified
ObjectProvider subSM = myEC.findObjectProvider(value);
int ownerAbsFieldNum = subSM.getClassMetaData().getAbsolutePositionOfMember(mmd.getEmbeddedMetaData().getOwnerMember());
if (ownerAbsFieldNum >= 0) {
flags |= FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER;
subSM.replaceFieldMakeDirty(ownerAbsFieldNum, myPC);
flags &= ~FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER;
}
}
}
}
use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.
the class DeleteFieldManager method storeObjectField.
/**
* Method to store an object field.
* @param fieldNumber Number of the field (absolute)
* @param value Value of the field
*/
public void storeObjectField(int fieldNumber, Object value) {
if (value != null) {
AbstractMemberMetaData mmd = op.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
ExecutionContext ec = op.getExecutionContext();
RelationType relationType = mmd.getRelationType(ec.getClassLoaderResolver());
if (relationType != RelationType.NONE) {
if (mmd.hasContainer()) {
processContainer(fieldNumber, value, mmd, ec, relationType);
} else {
processSingleValue(value, mmd, ec, relationType);
}
}
}
}
use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.
the class DetachFieldManager method internalFetchObjectField.
/**
* Method to fetch an object field whether it is collection/map, PC, or whatever for the detachment
* process.
* @param fieldNumber Number of the field
* @return The object
*/
protected Object internalFetchObjectField(int fieldNumber) {
SingleValueFieldManager sfv = new SingleValueFieldManager();
op.provideFields(new int[] { fieldNumber }, sfv);
Object value = sfv.fetchObjectField(fieldNumber);
Object detachedValue = null;
if (value != null) {
AbstractMemberMetaData mmd = op.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
if (mmd.hasContainer()) {
// 1-N, M-N Container
detachedValue = processContainer(fieldNumber, value, mmd);
} else {
detachedValue = processField(fieldNumber, value, mmd);
}
}
return detachedValue;
}
Aggregations