use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class PersistentClassROF method getObject.
/**
* Method to convert the current ResultSet row into a persistable Object.
* @return The persistable object.
*/
public T getObject() {
// Find the class of the returned object in this row of the ResultSet
String className = null;
boolean requiresInheritanceCheck = true;
StatementMappingIndex discrimMapIdx = resultMapping.getMappingForMemberPosition(SurrogateColumnType.DISCRIMINATOR.getFieldNumber());
if (discrimMapIdx != null) {
// Discriminator mapping registered so use that
try {
String discrimValue = rs.getString(discrimMapIdx.getColumnPositions()[0]);
if (discrimValue == null) {
// Discriminator has no value so return null object
NucleusLogger.DATASTORE_RETRIEVE.debug("Value of discriminator is null so assuming object is null");
return null;
}
JavaTypeMapping discrimMapping = discrimMapIdx.getMapping();
DiscriminatorMetaData dismd = (discrimMapping != null ? discrimMapping.getTable().getDiscriminatorMetaData() : null);
className = ec.getMetaDataManager().getClassNameFromDiscriminatorValue(discrimValue, dismd);
requiresInheritanceCheck = false;
} catch (SQLException sqle) {
NucleusLogger.DATASTORE_RETRIEVE.debug("Exception obtaining value of discriminator : " + sqle.getMessage());
}
} else if (resultMapping.getNucleusTypeColumnName() != null) {
// Extract the object type using the NucleusType column (if available)
try {
className = rs.getString(resultMapping.getNucleusTypeColumnName());
if (className == null) {
// Discriminator has no value so return null object
NucleusLogger.DATASTORE_RETRIEVE.debug("Value of determiner column is null so assuming object is null");
return null;
}
className = className.trim();
requiresInheritanceCheck = false;
} catch (SQLException sqle) {
// NucleusType column not found so ignore
}
}
ClassLoaderResolver clr = ec.getClassLoaderResolver();
Class pcClassForObject = persistentClass;
if (className != null) {
Class cls = (Class) resolvedClasses.get(className);
if (cls != null) {
pcClassForObject = cls;
} else {
if (persistentClass.getName().equals(className)) {
pcClassForObject = persistentClass;
} else {
pcClassForObject = clr.classForName(className, persistentClass.getClassLoader());
}
resolvedClasses.put(className, pcClassForObject);
}
}
if (requiresInheritanceCheck) {
// Check if no instantiable subclasses
String[] subclasses = ec.getMetaDataManager().getSubclassesForClass(pcClassForObject.getName(), false);
if (subclasses == null || subclasses.length == 0) {
requiresInheritanceCheck = false;
}
}
String warnMsg = null;
if (Modifier.isAbstract(pcClassForObject.getModifiers())) {
// Persistent class is abstract so we can't create instances of that type!
// This can happen if the user is using subclass-table and hasn't provided a discriminator in
// the table. Try going out one level and find a (single) concrete subclass
// TODO make this more robust and go out further
String[] subclasses = ec.getMetaDataManager().getSubclassesForClass(pcClassForObject.getName(), false);
if (subclasses != null) {
Class concreteSubclass = null;
int numConcreteSubclasses = 0;
for (int i = 0; i < subclasses.length; i++) {
Class subcls = clr.classForName(subclasses[i]);
if (!Modifier.isAbstract(subcls.getModifiers())) {
numConcreteSubclasses++;
concreteSubclass = subcls;
}
}
if (numConcreteSubclasses == 1) {
// Only one possible subclass, so use that
NucleusLogger.DATASTORE_RETRIEVE.warn(Localiser.msg("052300", pcClassForObject.getName(), concreteSubclass.getName()));
pcClassForObject = concreteSubclass;
} else if (numConcreteSubclasses == 0) {
throw new NucleusUserException(Localiser.msg("052301", pcClassForObject.getName()));
} else {
// More than 1 possible so notify the user. Really should return the abstract
warnMsg = "Found type=" + pcClassForObject + " but abstract and more than 1 concrete subclass (" + StringUtils.objectArrayToString(subclasses) + "). Really you need a discriminator to help identifying the type. Choosing " + concreteSubclass;
pcClassForObject = concreteSubclass;
requiresInheritanceCheck = true;
}
}
}
// Find the statement mappings and field numbers to use for the result class
// Caters for persistent-interfaces and the result class being an implementation
AbstractClassMetaData cmd = ec.getMetaDataManager().getMetaDataForClass(pcClassForObject, clr);
if (cmd == null) {
// TODO Improve this and check PK cols
return null;
}
int[] fieldNumbers = resultMapping.getMemberNumbers();
// TODO We need this on the first object only to generate the ResultSetGetter; can we optimise this?
StatementClassMapping mappingDefinition;
int[] mappedFieldNumbers;
if (rootCmd instanceof InterfaceMetaData) {
// Persistent-interface : create new mapping definition for a result type of the implementation
mappingDefinition = new StatementClassMapping();
mappingDefinition.setNucleusTypeColumnName(resultMapping.getNucleusTypeColumnName());
mappedFieldNumbers = new int[fieldNumbers.length];
for (int i = 0; i < fieldNumbers.length; i++) {
AbstractMemberMetaData mmd = rootCmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumbers[i]);
mappedFieldNumbers[i] = cmd.getAbsolutePositionOfMember(mmd.getName());
mappingDefinition.addMappingForMember(mappedFieldNumbers[i], resultMapping.getMappingForMemberPosition(fieldNumbers[i]));
}
} else {
// Persistent class
mappingDefinition = resultMapping;
mappedFieldNumbers = fieldNumbers;
}
if (resultSetGetter == null) {
// Use this result mapping definition for our ResultSetGetter
this.resultSetGetter = new ResultSetGetter(ec, rs, mappingDefinition, rootCmd);
}
// Extract any surrogate version
VersionMetaData vermd = cmd.getVersionMetaDataForClass();
Object surrogateVersion = null;
StatementMappingIndex versionMapping = null;
if (vermd != null) {
if (vermd.getFieldName() == null) {
versionMapping = resultMapping.getMappingForMemberPosition(SurrogateColumnType.VERSION.getFieldNumber());
} else {
AbstractMemberMetaData vermmd = cmd.getMetaDataForMember(vermd.getFieldName());
versionMapping = resultMapping.getMappingForMemberPosition(vermmd.getAbsoluteFieldNumber());
}
}
if (versionMapping != null) {
// Surrogate version column returned by query
JavaTypeMapping mapping = versionMapping.getMapping();
surrogateVersion = mapping.getObject(ec, rs, versionMapping.getColumnPositions());
}
// Extract the object from the ResultSet
T obj = null;
boolean needToSetVersion = false;
if (persistentClass.isInterface() && !cmd.isImplementationOfPersistentDefinition()) {
// Querying by interface, and not a generated implementation so use the metadata for the interface
cmd = ec.getMetaDataManager().getMetaDataForInterface(persistentClass, clr);
if (cmd == null) {
// Fallback to the value we had
cmd = ec.getMetaDataManager().getMetaDataForClass(pcClassForObject, clr);
}
}
if (cmd.getIdentityType() == IdentityType.APPLICATION) {
// Check if the PK field(s) are all null (implies null object, when using OUTER JOIN)
int[] pkNumbers = cmd.getPKMemberPositions();
boolean nullObject = true;
for (int i = 0; i < pkNumbers.length; i++) {
StatementMappingIndex pkIdx = mappingDefinition.getMappingForMemberPosition(pkNumbers[i]);
if (pkIdx == null) {
throw new NucleusException("You have just executed an SQL statement yet the information " + "for the primary key column(s) is not available! Please generate a testcase and report this issue");
}
int[] colPositions = pkIdx.getColumnPositions();
for (int j = 0; j < colPositions.length; j++) {
try {
Object pkObj = rs.getObject(colPositions[j]);
if (pkObj != null) {
nullObject = false;
break;
}
} catch (SQLException sqle) {
NucleusLogger.DATASTORE_RETRIEVE.warn("Exception thrown while retrieving results ", sqle);
}
if (!nullObject) {
break;
}
}
}
if (!nullObject) {
// Retrieve the object with this application-identity
if (warnMsg != null) {
NucleusLogger.DATASTORE_RETRIEVE.warn(warnMsg);
}
Object id = IdentityUtils.getApplicationIdentityForResultSetRow(ec, cmd, pcClassForObject, requiresInheritanceCheck, resultSetGetter);
String idClassName = IdentityUtils.getTargetClassNameForIdentity(id);
if (idClassName != null) {
// "identity" defines the class name
pcClassForObject = clr.classForName(idClassName);
}
obj = findObjectWithIdAndLoadFields(id, mappedFieldNumbers, pcClassForObject, cmd, surrogateVersion);
}
} else if (cmd.getIdentityType() == IdentityType.DATASTORE) {
// Generate the "id" for this object (of type pcClassForObject), and find the object for that
StatementMappingIndex datastoreIdMapping = resultMapping.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
JavaTypeMapping mapping = datastoreIdMapping.getMapping();
Object id = mapping.getObject(ec, rs, datastoreIdMapping.getColumnPositions());
if (id != null) {
String idClassName = IdentityUtils.getTargetClassNameForIdentity(id);
if (!pcClassForObject.getName().equals(idClassName)) {
// Get a DatastoreId for the right inheritance level
id = ec.getNucleusContext().getIdentityManager().getDatastoreId(pcClassForObject.getName(), IdentityUtils.getTargetKeyForDatastoreIdentity(id));
}
if (warnMsg != null) {
NucleusLogger.DATASTORE_RETRIEVE.warn(warnMsg);
}
if (mappedFieldNumbers == null) {
obj = (T) ec.findObject(id, false, requiresInheritanceCheck, null);
needToSetVersion = true;
} else {
obj = findObjectWithIdAndLoadFields(id, mappedFieldNumbers, requiresInheritanceCheck ? null : pcClassForObject, cmd, surrogateVersion);
}
}
} else if (cmd.getIdentityType() == IdentityType.NONDURABLE) {
String classNameForId = className;
if (className == null) {
// No discriminator info from the query, so just fallback to default type
classNameForId = cmd.getFullClassName();
}
Object id = ec.newObjectId(classNameForId, null);
if (mappedFieldNumbers == null) {
obj = (T) ec.findObject(id, false, requiresInheritanceCheck, null);
needToSetVersion = true;
} else {
obj = findObjectWithIdAndLoadFields(id, fieldNumbers, pcClassForObject, cmd, surrogateVersion);
}
}
if (obj != null && needToSetVersion) {
// Set the version of the object where possible
if (surrogateVersion != null) {
ObjectProvider objOP = ec.findObjectProvider(obj);
objOP.setVersion(surrogateVersion);
} else {
if (vermd != null && vermd.getFieldName() != null) {
// Version stored in a normal field
int versionFieldNumber = rootCmd.getMetaDataForMember(vermd.getFieldName()).getAbsoluteFieldNumber();
if (resultMapping.getMappingForMemberPosition(versionFieldNumber) != null) {
ObjectProvider objOP = ec.findObjectProvider(obj);
Object verFieldValue = objOP.provideField(versionFieldNumber);
if (verFieldValue != null) {
objOP.setVersion(verFieldValue);
}
}
}
}
}
return obj;
}
use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class QueryToSQLMapper method getValueForObjectField.
/**
* Convenience method to return the value of a field of the supplied object.
* If the object is null then returns null for the field.
* @param obj The object
* @param fieldName The field name
* @return The field value
*/
protected Object getValueForObjectField(Object obj, String fieldName) {
if (obj != null) {
Object paramFieldValue = null;
if (ec.getApiAdapter().isPersistable(obj)) {
ObjectProvider paramOP = ec.findObjectProvider(obj);
AbstractClassMetaData paramCmd = ec.getMetaDataManager().getMetaDataForClass(obj.getClass(), clr);
AbstractMemberMetaData paramFieldMmd = paramCmd.getMetaDataForMember(fieldName);
if (paramOP != null) {
paramOP.isLoaded(paramFieldMmd.getAbsoluteFieldNumber());
paramFieldValue = paramOP.provideField(paramFieldMmd.getAbsoluteFieldNumber());
} else {
paramFieldValue = ClassUtils.getValueOfFieldByReflection(obj, fieldName);
}
} else {
paramFieldValue = ClassUtils.getValueOfFieldByReflection(obj, fieldName);
}
return paramFieldValue;
}
return null;
}
use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class OracleSerialisedPCMapping method insertPostProcessing.
/**
* Retrieve the empty BLOB created by the insert statement and write out the
* current BLOB field value to the Oracle BLOB object
* @param op the current ObjectProvider
*/
public void insertPostProcessing(ObjectProvider op) {
Object value = op.provideField(mmd.getAbsoluteFieldNumber());
ObjectProvider sm = null;
if (value != null) {
ExecutionContext ec = op.getExecutionContext();
sm = ec.findObjectProvider(value);
if (sm == null || sm.getExecutionContext().getApiAdapter().getExecutionContext(value) == null) {
// Assign a ObjectProvider to the serialised object since none present
sm = ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, value, false, op, mmd.getAbsoluteFieldNumber());
}
}
if (sm != null) {
sm.setStoringPC();
}
// Generate the contents for the BLOB
byte[] bytes = new byte[0];
if (value != null) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(value);
bytes = baos.toByteArray();
} catch (IOException e1) {
// Do Nothing
}
}
// Update the BLOB
OracleBlobRDBMSMapping.updateBlobColumn(op, getTable(), getDatastoreMapping(0), bytes);
if (sm != null) {
sm.unsetStoringPC();
}
}
use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class PersistableMapping method preDelete.
/**
* Method executed just before the owning object is deleted, allowing tidying up of any relation information.
* @param op ObjectProvider for the owner
*/
public void preDelete(ObjectProvider op) {
int fieldNumber = mmd.getAbsoluteFieldNumber();
if (!op.isFieldLoaded(fieldNumber)) {
// makes sure field is loaded
try {
op.loadField(fieldNumber);
} catch (NucleusObjectNotFoundException onfe) {
// Already deleted so just return
return;
}
}
Object pc = op.provideField(fieldNumber);
pc = mmd.isSingleCollection() ? SCOUtils.singleCollectionValue(getStoreManager().getNucleusContext().getTypeManager(), pc) : pc;
if (pc == null) {
// Null value so nothing to do
return;
}
ExecutionContext ec = op.getExecutionContext();
ClassLoaderResolver clr = ec.getClassLoaderResolver();
// N-1 Uni, so delete join table entry
RelationType relationType = mmd.getRelationType(clr);
if (relationType == RelationType.MANY_TO_ONE_UNI) {
// Update join table entry
PersistableRelationStore store = (PersistableRelationStore) storeMgr.getBackingStoreForField(clr, mmd, mmd.getType());
store.remove(op);
}
// Check if we should delete the related object when this object is deleted
boolean dependent = mmd.isDependent();
if (mmd.isCascadeRemoveOrphans()) {
// JPA allows "orphan removal" to define deletion of the other side
dependent = true;
}
// Check if the field has a FK defined
AbstractMemberMetaData[] relatedMmds = mmd.getRelatedMemberMetaData(clr);
// TODO Cater for more than 1 related field
boolean hasFK = false;
if (!dependent) {
// Not dependent, so check if the datastore has a FK and will take care of it for us
if (mmd.getForeignKeyMetaData() != null) {
hasFK = true;
}
if (RelationType.isBidirectional(relationType) && relatedMmds[0].getForeignKeyMetaData() != null) {
hasFK = true;
}
if (ec.getStringProperty(PropertyNames.PROPERTY_DELETION_POLICY).equals("JDO2")) {
// JDO doesn't currently take note of foreign-key
hasFK = false;
}
}
// There may be some corner cases that this code doesn't yet cater for
if (relationType == RelationType.ONE_TO_ONE_UNI || (relationType == RelationType.ONE_TO_ONE_BI && mmd.getMappedBy() == null)) {
// 1-1 with FK at this side (owner of the relation)
if (dependent) {
boolean relatedObjectDeleted = ec.getApiAdapter().isDeleted(pc);
if (isNullable() && !relatedObjectDeleted) {
// Other object not yet deleted, but the field is nullable so just null out the FK
// TODO Not doing this would cause errors in 1-1 uni relations (e.g AttachDetachTest)
// TODO Log this since it affects the resultant objects
op.replaceFieldMakeDirty(fieldNumber, null);
storeMgr.getPersistenceHandler().updateObject(op, new int[] { fieldNumber });
if (!relatedObjectDeleted) {
// Mark the other object for deletion since not yet tagged
ec.deleteObjectInternal(pc);
}
} else {
// Can't just delete the other object since that would cause a FK constraint violation. Do nothing - handled by DeleteRequest on other object
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.DATASTORE_PERSIST.debug(Localiser.msg("041017", StringUtils.toJVMIDString(op.getObject()), mmd.getFullFieldName()));
}
}
} else {
// We're deleting the FK at this side so shouldn't be an issue
AbstractMemberMetaData relatedMmd = mmd.getRelatedMemberMetaDataForObject(clr, op.getObject(), pc);
if (relatedMmd != null) {
ObjectProvider otherOP = ec.findObjectProvider(pc);
if (otherOP != null) {
// Managed Relations : 1-1 bidir, so null out the object at the other
Object currentValue = otherOP.provideField(relatedMmd.getAbsoluteFieldNumber());
if (currentValue != null) {
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("041019", StringUtils.toJVMIDString(pc), relatedMmd.getFullFieldName(), op.getObjectAsPrintable()));
}
otherOP.replaceFieldMakeDirty(relatedMmd.getAbsoluteFieldNumber(), null);
if (ec.getManageRelations()) {
otherOP.getExecutionContext().getRelationshipManager(otherOP).relationChange(relatedMmd.getAbsoluteFieldNumber(), op.getObject(), null);
}
}
}
}
}
} else if (relationType == RelationType.ONE_TO_ONE_BI && mmd.getMappedBy() != null) {
// 1-1 with FK at other side
DatastoreClass relatedTable = storeMgr.getDatastoreClass(relatedMmds[0].getClassName(), clr);
JavaTypeMapping relatedMapping = relatedTable.getMemberMapping(relatedMmds[0]);
boolean isNullable = relatedMapping.isNullable();
ObjectProvider otherOP = ec.findObjectProvider(pc);
if (dependent) {
if (isNullable) {
// Null out the FK in the datastore using a direct update (since we are deleting)
otherOP.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
storeMgr.getPersistenceHandler().updateObject(otherOP, new int[] { relatedMmds[0].getAbsoluteFieldNumber() });
}
// Mark the other object for deletion
ec.deleteObjectInternal(pc);
} else if (!hasFK) {
if (isNullable()) {
Object currentRelatedValue = otherOP.provideField(relatedMmds[0].getAbsoluteFieldNumber());
if (currentRelatedValue != null) {
// Null out the FK in the datastore using a direct update (since we are deleting)
otherOP.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
storeMgr.getPersistenceHandler().updateObject(otherOP, new int[] { relatedMmds[0].getAbsoluteFieldNumber() });
// Managed Relations : 1-1 bidir, so null out the object at the other
if (ec.getManageRelations()) {
otherOP.getExecutionContext().getRelationshipManager(otherOP).relationChange(relatedMmds[0].getAbsoluteFieldNumber(), op.getObject(), null);
}
}
} else {
// TODO Remove it
}
} else {
// User has a FK defined (in MetaData) so let the datastore take care of it
}
} else if (relationType == RelationType.MANY_TO_ONE_BI) {
ObjectProvider otherOP = ec.findObjectProvider(pc);
if (relatedMmds[0].getJoinMetaData() == null) {
// N-1 with FK at this side
if (otherOP.isDeleting()) {
// Other object is being deleted too but this side has the FK so just delete this object
} else {
// Other object is not being deleted so delete it if necessary
if (dependent) {
if (isNullable()) {
// TODO Datastore nullability info can be unreliable so try to avoid this call
// Null out the FK in the datastore using a direct update (since we are deleting)
op.replaceFieldMakeDirty(fieldNumber, null);
storeMgr.getPersistenceHandler().updateObject(op, new int[] { fieldNumber });
}
if (ec.getApiAdapter().isDeleted(pc)) {
// Object is already tagged for deletion but we're deleting the FK so leave til flush()
} else {
// Mark the other object for deletion
ec.deleteObjectInternal(pc);
}
} else {
// Managed Relations : remove element from collection/map
if (relatedMmds[0].hasCollection()) {
// Only update the other side if not already being deleted
if (!ec.getApiAdapter().isDeleted(otherOP.getObject()) && !otherOP.isDeleting()) {
// Make sure the other object is updated in any caches
ec.markDirty(otherOP, false);
// Make sure collection field is loaded
otherOP.isLoaded(relatedMmds[0].getAbsoluteFieldNumber());
Collection otherColl = (Collection) otherOP.provideField(relatedMmds[0].getAbsoluteFieldNumber());
if (otherColl != null) {
if (ec.getManageRelations()) {
otherOP.getExecutionContext().getRelationshipManager(otherOP).relationRemove(relatedMmds[0].getAbsoluteFieldNumber(), op.getObject());
}
// TODO Localise this message
NucleusLogger.PERSISTENCE.debug("ManagedRelationships : delete of object causes removal from collection at " + relatedMmds[0].getFullFieldName());
otherColl.remove(op.getObject());
}
}
} else if (relatedMmds[0].hasMap()) {
// TODO Cater for maps, but what is the key/value pair ?
}
}
}
} else {
// N-1 with join table so no FK here so need to remove from Collection/Map first? (managed relations)
if (dependent) {
// Mark the other object for deletion
ec.deleteObjectInternal(pc);
} else {
// Managed Relations : remove element from collection/map
if (relatedMmds[0].hasCollection()) {
// Only update the other side if not already being deleted
if (!ec.getApiAdapter().isDeleted(otherOP.getObject()) && !otherOP.isDeleting()) {
// Make sure the other object is updated in any caches
ec.markDirty(otherOP, false);
// Make sure the other object has the collection loaded so does this change
otherOP.isLoaded(relatedMmds[0].getAbsoluteFieldNumber());
Collection otherColl = (Collection) otherOP.provideField(relatedMmds[0].getAbsoluteFieldNumber());
if (otherColl != null) {
// TODO Localise this
NucleusLogger.PERSISTENCE.debug("ManagedRelationships : delete of object causes removal from collection at " + relatedMmds[0].getFullFieldName());
otherColl.remove(op.getObject());
}
}
} else if (relatedMmds[0].hasMap()) {
// TODO Cater for maps, but what is the key/value pair ?
}
}
}
} else if (relationType == RelationType.MANY_TO_ONE_UNI) {
// N-1 uni with join table
if (dependent) {
// Mark the other object for deletion
ec.deleteObjectInternal(pc);
}
} else {
// No relation so what is this field ?
}
}
use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class PersistableMapping method getValueForDatastoreMapping.
/**
* Method to return the value to be stored in the specified datastore index given the overall value for this java type.
* @param nucleusCtx Context
* @param index The datastore index
* @param value The overall value for this java type
* @return The value for this datastore index
*/
public Object getValueForDatastoreMapping(NucleusContext nucleusCtx, int index, Object value) {
ExecutionContext ec = nucleusCtx.getApiAdapter().getExecutionContext(value);
if (cmd == null) {
cmd = nucleusCtx.getMetaDataManager().getMetaDataForClass(getType(), ec != null ? ec.getClassLoaderResolver() : nucleusCtx.getClassLoaderResolver(null));
}
if (cmd.getIdentityType() == IdentityType.APPLICATION) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(cmd.getPKMemberPositions()[index]);
ObjectProvider op = null;
if (ec != null) {
op = ec.findObjectProvider(value);
}
if (op == null) {
// Transient or detached maybe, so use reflection to get PK field values
if (mmd instanceof FieldMetaData) {
return ClassUtils.getValueOfFieldByReflection(value, mmd.getName());
}
return ClassUtils.getValueOfMethodByReflection(value, ClassUtils.getJavaBeanGetterName(mmd.getName(), false));
}
if (!mmd.isPrimaryKey()) {
// Make sure the field is loaded
op.isLoaded(mmd.getAbsoluteFieldNumber());
}
FieldManager fm = new SingleValueFieldManager();
op.provideFields(new int[] { mmd.getAbsoluteFieldNumber() }, fm);
return fm.fetchObjectField(mmd.getAbsoluteFieldNumber());
} else if (cmd.getIdentityType() == IdentityType.DATASTORE) {
Object id = nucleusCtx.getApiAdapter().getIdForObject(value);
return id != null ? IdentityUtils.getTargetKeyForDatastoreIdentity(id) : null;
}
return null;
}
Aggregations