sqlMapping = getSQLTableMappingForAlias(candidateAlias);
primaryName = candidateAlias;
}
}
AbstractClassMetaData cmd = sqlMapping.cmd;
JavaTypeMapping mapping = sqlMapping.mapping;
while (iter.hasNext())
{
String component = iter.next();
primaryName += "." + component; // fully-qualified primary name
// Derive SQLTableMapping for this component
SQLTableMapping sqlMappingNew = getSQLTableMappingForAlias(primaryName);
if (sqlMappingNew == null)
{
// Table not present for this primary
AbstractMemberMetaData mmd = cmd.getMetaDataForMember(component);
if (mmd == null)
{
// Not valid member name
throw new NucleusUserException(LOCALISER.msg("021062", component, cmd.getFullClassName()));
}
else if (mmd.getPersistenceModifier() != FieldPersistenceModifier.PERSISTENT)
{
throw new NucleusUserException("Field "+ mmd.getFullFieldName() + " is not marked as persistent so cannot be queried");
}
// Find the table and the mapping for this field in the table
SQLTable sqlTbl = null;
if (mapping instanceof EmbeddedMapping)
{
// Embedded into the current table
sqlTbl = sqlMapping.table;
mapping = ((EmbeddedMapping)mapping).getJavaTypeMapping(component);
}
else
{
DatastoreClass table = storeMgr.getDatastoreClass(cmd.getFullClassName(), clr);
if (table == null)
{
AbstractClassMetaData[] subCmds = storeMgr.getClassesManagingTableForClass(cmd, clr);
if (subCmds.length == 1)
{
table = storeMgr.getDatastoreClass(subCmds[0].getFullClassName(), clr);
}
else
{
throw new NucleusUserException("Unable to find table for primary " + primaryName +
" since the class " + cmd.getFullClassName() + " is managed in multiple tables");
}
}
mapping = table.getMemberMapping(mmd);
sqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(theStmt, sqlMapping.table, mapping);
}
int relationType = mmd.getRelationType(clr);
switch (relationType)
{
case Relation.NONE :
sqlMappingNew = new SQLTableMapping(sqlTbl, cmd, mapping);
cmd = sqlMappingNew.cmd;
setSQLTableMappingForAlias(primaryName, sqlMappingNew);
break;
case Relation.ONE_TO_ONE_UNI :
case Relation.ONE_TO_ONE_BI :
if (mmd.getMappedBy() != null)
{
// FK in other table so join to that first
AbstractMemberMetaData relMmd = mmd.getRelatedMemberMetaData(clr)[0];
if (relMmd.getAbstractClassMetaData().isEmbeddedOnly())
{
// Member is embedded, so keep same SQL table mapping
sqlMappingNew = sqlMapping;
cmd = relMmd.getAbstractClassMetaData();
}
else
{
// Member is in own table, so move to that SQL table mapping
DatastoreClass relTable = storeMgr.getDatastoreClass(mmd.getTypeName(), clr);
JavaTypeMapping relMapping = relTable.getMemberMapping(relMmd);
// Join to related table unless we already have the join in place
sqlTbl = theStmt.getTable(relTable, primaryName);
if (sqlTbl == null)
{
sqlTbl = SQLStatementHelper.addJoinForOneToOneRelation(theStmt,
sqlMapping.table.getTable().getIdMapping(), sqlMapping.table,
relMapping, relTable, null, null, primaryName, defaultJoinType);
}
if (iter.hasNext())
{
sqlMappingNew = new SQLTableMapping(sqlTbl, relMmd.getAbstractClassMetaData(),
relTable.getIdMapping());
cmd = sqlMappingNew.cmd;
}
else
{
sqlMappingNew = new SQLTableMapping(sqlTbl, cmd, relTable.getIdMapping());
cmd = sqlMappingNew.cmd;
}
}
}
else
{
// FK is at this side, so only join if further component provided, or if forcing
if (forceJoin == null && !iter.hasNext())
{
if (primExpr.getParent() != null &&
primExpr.getParent().getOperator() == Expression.OP_CAST)
{
// Cast and not an interface field, so do a join to the table of the persistable object
if (!(mapping instanceof ReferenceMapping))
{
// Don't join with interface field since represents multiple implementations
// and the cast will be a restrict on which implementation to join to
forceJoin = Boolean.TRUE;
}
}
}
if (iter.hasNext() || Boolean.TRUE.equals(forceJoin))
{
AbstractClassMetaData relCmd = null;
JavaTypeMapping relMapping = null;
DatastoreClass relTable = null;
if (relationType == Relation.ONE_TO_ONE_BI)
{
AbstractMemberMetaData relMmd = mmd.getRelatedMemberMetaData(clr)[0];
relCmd = relMmd.getAbstractClassMetaData();
}
else
{
relCmd = ec.getMetaDataManager().getMetaDataForClass(mmd.getTypeName(), clr);
}
if (relCmd != null && relCmd.isEmbeddedOnly())
{
// Member is embedded so keep same SQL table mapping
sqlMappingNew = sqlMapping;
cmd = relCmd;
}
else
{
// Member is in own table, so move to that SQL table mapping
relTable = storeMgr.getDatastoreClass(relCmd.getFullClassName(), clr);
relMapping = relTable.getIdMapping();
// Join to other table unless we already have the join in place
sqlTbl = theStmt.getTable(relTable, primaryName);
if (sqlTbl == null)