use of org.datanucleus.metadata.DiscriminatorMetaData in project datanucleus-api-jdo by datanucleus.
the class InheritanceMetadataImpl method newDiscriminatorMetadata.
/* (non-Javadoc)
* @see javax.jdo.metadata.InheritanceMetadata#newDiscriminatorMetadata()
*/
public DiscriminatorMetadata newDiscriminatorMetadata() {
DiscriminatorMetaData internalDismd = getInternal().newDiscriminatorMetadata();
DiscriminatorMetadataImpl dismd = new DiscriminatorMetadataImpl(internalDismd);
dismd.parent = this;
return dismd;
}
use of org.datanucleus.metadata.DiscriminatorMetaData in project datanucleus-rdbms by datanucleus.
the class RDBMSStoreHelper method getClassNameForIdUsingDiscriminator.
/**
* Utility that does a discriminator candidate query for the specified candidate and subclasses
* and returns the class name of the instance that has the specified identity (if any).
* @param storeMgr RDBMS StoreManager
* @param ec execution context
* @param id The id
* @param cmd Metadata for the root candidate class
* @return Name of the class with this identity (or null if none found)
*/
public static String getClassNameForIdUsingDiscriminator(RDBMSStoreManager storeMgr, ExecutionContext ec, Object id, AbstractClassMetaData cmd) {
// Check for input error
if (cmd == null || id == null) {
return null;
}
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
ClassLoaderResolver clr = ec.getClassLoaderResolver();
DatastoreClass primaryTable = storeMgr.getDatastoreClass(cmd.getFullClassName(), clr);
// Form the query to find which one of these classes has the instance with this id
DiscriminatorStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, clr.classForName(cmd.getFullClassName()), true, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_RESTRICT_DISCRIM);
SelectStatement sqlStmt = stmtGen.getStatement(ec);
// Select the discriminator
JavaTypeMapping discrimMapping = primaryTable.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, true);
SQLTable discrimSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), discrimMapping);
sqlStmt.select(discrimSqlTbl, discrimMapping, null);
// Restrict to this id
JavaTypeMapping idMapping = primaryTable.getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression sqlFldExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), idMapping);
SQLExpression sqlFldVal = exprFactory.newLiteralParameter(sqlStmt, idParamMapping, id, "ID");
sqlStmt.whereAnd(sqlFldExpr.eq(sqlFldVal), true);
// Perform the query
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
if (ec.getSerializeReadForClass(cmd.getFullClassName())) {
sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
}
try {
PreparedStatement ps = SQLStatementHelper.getPreparedStatementForSQLStatement(sqlStmt, ec, mconn, null, null);
String statement = sqlStmt.getSQLText().toSQL();
try {
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps);
try {
while (rs.next()) {
DiscriminatorMetaData dismd = discrimMapping.getTable().getDiscriminatorMetaData();
return RDBMSQueryUtils.getClassNameFromDiscriminatorResultSetRow(discrimMapping, dismd, rs, ec);
}
} finally {
rs.close();
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException sqe) {
NucleusLogger.DATASTORE.error("Exception thrown on querying of discriminator for id", sqe);
throw new NucleusDataStoreException(sqe.toString(), sqe);
}
return null;
}
use of org.datanucleus.metadata.DiscriminatorMetaData in project datanucleus-rdbms by datanucleus.
the class UnionStatementGenerator method getSelectStatementForCandidate.
/**
* Convenience method to return the SelectStatement for a particular class.
* Returns a SelectStatement with primaryTable of the "candidateTable", and which joins to the table of the class (if different).
* @param className The class name to generate the statement for
* @param ec ExecutionContext
* @return The SelectStatement
*/
protected SelectStatement getSelectStatementForCandidate(String className, ExecutionContext ec) {
DatastoreClass table = storeMgr.getDatastoreClass(className, clr);
if (table == null) {
// Subclass-table, so persisted into table(s) of subclasses
NucleusLogger.GENERAL.info("Generation of statement to retrieve objects of type " + candidateType.getName() + (includeSubclasses ? " including subclasses " : "") + " attempted to include " + className + " but this has no table of its own; ignored");
// TODO Cater for use of single subclass-table
return null;
}
// Start from an SQL SELECT of the candidate table
SelectStatement stmt = new SelectStatement(parentStmt, storeMgr, candidateTable, candidateTableAlias, candidateTableGroupName);
stmt.setClassLoaderResolver(clr);
stmt.setCandidateClassName(className);
String tblGroupName = stmt.getPrimaryTable().getGroupName();
if (table != candidateTable) {
// INNER JOIN from the root candidate table to this candidates table
JavaTypeMapping candidateIdMapping = candidateTable.getIdMapping();
JavaTypeMapping tableIdMapping = table.getIdMapping();
SQLTable tableSqlTbl = stmt.join(JoinType.INNER_JOIN, null, candidateIdMapping, table, null, tableIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
tblGroupName = tableSqlTbl.getGroupName();
}
// Add any discriminator restriction in this table for the specified class
// Caters for the case where we have more than 1 class stored in this table
SQLExpressionFactory factory = storeMgr.getSQLExpressionFactory();
JavaTypeMapping discriminatorMapping = table.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, false);
DiscriminatorMetaData discriminatorMetaData = table.getDiscriminatorMetaData();
if (discriminatorMapping != null && discriminatorMetaData.getStrategy() != DiscriminatorStrategy.NONE) {
// Restrict to valid discriminator values where we have a discriminator specified on this table
AbstractClassMetaData targetCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(className, clr);
SQLExpression discExpr = factory.newExpression(stmt, stmt.getPrimaryTable(), discriminatorMapping);
SQLExpression discValExpr = factory.newLiteral(stmt, discriminatorMapping, targetCmd.getDiscriminatorValue());
stmt.whereAnd(discExpr.eq(discValExpr), false);
}
JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
if (multitenancyMapping != null) {
// Multi-tenancy restriction
AbstractClassMetaData cmd = table.getClassMetaData();
SQLTable tenantSqlTbl = stmt.getTable(multitenancyMapping.getTable(), tblGroupName);
SQLExpression tenantExpr = stmt.getSQLExpressionFactory().newExpression(stmt, tenantSqlTbl, multitenancyMapping);
SQLExpression tenantVal = stmt.getSQLExpressionFactory().newLiteral(stmt, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, cmd));
stmt.whereAnd(tenantExpr.eq(tenantVal), true);
}
JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
if (softDeleteMapping != null && !hasOption(OPTION_INCLUDE_SOFT_DELETES)) {
// Soft-delete restriction
SQLTable softDeleteSqlTbl = stmt.getTable(softDeleteMapping.getTable(), tblGroupName);
SQLExpression softDeleteExpr = stmt.getSQLExpressionFactory().newExpression(stmt, softDeleteSqlTbl, softDeleteMapping);
SQLExpression softDeleteVal = stmt.getSQLExpressionFactory().newLiteral(stmt, softDeleteMapping, Boolean.FALSE);
stmt.whereAnd(softDeleteExpr.eq(softDeleteVal), true);
}
// Eliminate any subclasses (catered for in separate UNION statement)
Iterator<String> subIter = storeMgr.getSubClassesForClass(className, false, clr).iterator();
while (subIter.hasNext()) {
String subclassName = subIter.next();
DatastoreClass[] subclassTables = null;
DatastoreClass subclassTable = storeMgr.getDatastoreClass(subclassName, clr);
if (subclassTable == null) {
AbstractClassMetaData targetSubCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(subclassName, clr);
AbstractClassMetaData[] targetSubCmds = storeMgr.getClassesManagingTableForClass(targetSubCmd, clr);
subclassTables = new DatastoreClass[targetSubCmds.length];
for (int i = 0; i < targetSubCmds.length; i++) {
subclassTables[i] = storeMgr.getDatastoreClass(targetSubCmds[i].getFullClassName(), clr);
}
} else {
subclassTables = new DatastoreClass[1];
subclassTables[0] = subclassTable;
}
for (int i = 0; i < subclassTables.length; i++) {
if (subclassTables[i] != table) {
// Subclass of our class is stored in different table to the candidate so exclude it
// Adds FROM clause of "LEFT OUTER JOIN {subTable} ON ..."
// and WHERE clause of "{subTable}.ID = NULL"
JavaTypeMapping tableIdMapping = table.getIdMapping();
JavaTypeMapping subclassIdMapping = subclassTables[i].getIdMapping();
SQLTable sqlTableSubclass = stmt.join(JoinType.LEFT_OUTER_JOIN, null, tableIdMapping, subclassTables[i], null, subclassIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
SQLExpression subclassIdExpr = factory.newExpression(stmt, sqlTableSubclass, subclassIdMapping);
SQLExpression nullExpr = new NullLiteral(stmt, null, null, null);
stmt.whereAnd(subclassIdExpr.eq(nullExpr), false);
}
}
}
if (hasOption(OPTION_SELECT_DN_TYPE)) {
// Add SELECT of dummy metadata for this class ("'mydomain.MyClass' AS DN_TYPE")
addTypeSelectForClass(stmt, className);
}
return stmt;
}
use of org.datanucleus.metadata.DiscriminatorMetaData in project datanucleus-rdbms by datanucleus.
the class UnionStatementGenerator method getSQLStatementForCandidateViaJoin.
/**
* Convenience method to return the SQLStatement for a particular class selecting a join table.
* Returns a SQLStatement with primaryTable of the "joinTable", and which joins to the table of the class.
* @param className The class name to generate the statement for
* @return The SQLStatement
*/
protected SelectStatement getSQLStatementForCandidateViaJoin(String className) {
DatastoreClass table = storeMgr.getDatastoreClass(className, clr);
if (table == null) {
// TODO Cater for use of single subclass-table
throw new NucleusException("We do not currently support a UNION statement for class=" + className + " since it has no table of its own");
}
// Start from an SQL SELECT of the join table
SelectStatement stmt = new SelectStatement(parentStmt, storeMgr, joinTable, joinTableAlias, candidateTableGroupName);
stmt.setClassLoaderResolver(clr);
stmt.setCandidateClassName(className);
// INNER/LEFT OUTER JOIN from the join table to the root candidate table
// If we allow nulls we do a left outer join here, otherwise an inner join
SQLTable candidateSQLTable = null;
if (candidateTable != null) {
// We have a root candidate table, so join to that
JavaTypeMapping candidateIdMapping = candidateTable.getIdMapping();
if (hasOption(OPTION_ALLOW_NULLS)) {
// Put element table in same table group since all relates to the elements
candidateSQLTable = stmt.join(JoinType.LEFT_OUTER_JOIN, null, joinElementMapping, candidateTable, null, candidateIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
} else {
// Put element table in same table group since all relates to the elements
candidateSQLTable = stmt.join(JoinType.INNER_JOIN, null, joinElementMapping, candidateTable, null, candidateIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
}
// Join the root candidate table to this particular candidate table
if (table != candidateTable) {
// INNER JOIN from the root candidate table to this candidates table
stmt.join(JoinType.INNER_JOIN, candidateSQLTable, candidateIdMapping, table, null, table.getIdMapping(), null, stmt.getPrimaryTable().getGroupName(), true);
}
} else {
// No root candidate table, so join direct to this candidate
JavaTypeMapping candidateIdMapping = table.getIdMapping();
if (hasOption(OPTION_ALLOW_NULLS)) {
// Put element table in same table group since all relates to the elements
candidateSQLTable = stmt.join(JoinType.LEFT_OUTER_JOIN, null, joinElementMapping, table, null, candidateIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
} else {
// Put element table in same table group since all relates to the elements
candidateSQLTable = stmt.join(JoinType.INNER_JOIN, null, joinElementMapping, table, null, candidateIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
}
}
// Add any discriminator restriction in the table for the specified class
// Caters for the case where we have more than 1 class stored in this table
SQLExpressionFactory factory = storeMgr.getSQLExpressionFactory();
JavaTypeMapping discriminatorMapping = table.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, false);
DiscriminatorMetaData discriminatorMetaData = table.getDiscriminatorMetaData();
if (discriminatorMapping != null && discriminatorMetaData.getStrategy() != DiscriminatorStrategy.NONE) {
// Restrict to valid discriminator value where we have a discriminator specified on this table
BooleanExpression discExpr = SQLStatementHelper.getExpressionForDiscriminatorForClass(stmt, className, discriminatorMetaData, discriminatorMapping, stmt.getPrimaryTable(), clr);
stmt.whereAnd(discExpr, false);
}
// Eliminate any subclasses (catered for in separate UNION statement)
Iterator<String> subIter = storeMgr.getSubClassesForClass(className, false, clr).iterator();
while (subIter.hasNext()) {
String subclassName = subIter.next();
DatastoreClass[] subclassTables = null;
DatastoreClass subclassTable = storeMgr.getDatastoreClass(subclassName, clr);
if (subclassTable == null) {
AbstractClassMetaData targetSubCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(subclassName, clr);
AbstractClassMetaData[] targetSubCmds = storeMgr.getClassesManagingTableForClass(targetSubCmd, clr);
subclassTables = new DatastoreClass[targetSubCmds.length];
for (int i = 0; i < targetSubCmds.length; i++) {
subclassTables[i] = storeMgr.getDatastoreClass(targetSubCmds[i].getFullClassName(), clr);
}
} else {
subclassTables = new DatastoreClass[1];
subclassTables[0] = subclassTable;
}
for (int i = 0; i < subclassTables.length; i++) {
if (subclassTables[i] != table) {
// Subclass of our class is stored in different table to the candidate so exclude it
// Adds FROM clause of "LEFT OUTER JOIN {subTable} ON ..."
// and WHERE clause of "{subTable}.ID = NULL"
JavaTypeMapping subclassIdMapping = subclassTables[i].getIdMapping();
SQLTable sqlTableSubclass = stmt.join(JoinType.LEFT_OUTER_JOIN, null, joinElementMapping, subclassTables[i], null, subclassIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
SQLExpression subclassIdExpr = factory.newExpression(stmt, sqlTableSubclass, subclassIdMapping);
SQLExpression nullExpr = new NullLiteral(stmt, null, null, null);
stmt.whereAnd(subclassIdExpr.eq(nullExpr), false);
}
}
}
if (hasOption(OPTION_SELECT_DN_TYPE)) {
// Add SELECT of dummy metadata for this class ("'mydomain.MyClass' AS DN_TYPE")
addTypeSelectForClass(stmt, className);
}
return stmt;
}
use of org.datanucleus.metadata.DiscriminatorMetaData 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;
}
Aggregations