use of org.datanucleus.store.rdbms.RDBMSStoreManager in project datanucleus-rdbms by datanucleus.
the class JDOQLQuery method compileQueryUpdate.
/**
* Method to compile the query for RDBMS for a bulk update.
* @param parameterValues The parameter values (if any)
* @param candidateCmd Meta-data for the candidate class
*/
protected void compileQueryUpdate(Map parameterValues, AbstractClassMetaData candidateCmd) {
Expression[] updateExprs = compilation.getExprUpdate();
if (updateExprs == null || updateExprs.length == 0) {
// Nothing to update
return;
}
// Generate statement for candidate
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
DatastoreClass candidateTbl = storeMgr.getDatastoreClass(candidateCmd.getFullClassName(), clr);
if (candidateTbl == null) {
throw new NucleusDataStoreException("Bulk update of " + candidateCmd.getFullClassName() + " not supported since candidate has no table of its own");
}
List<BulkTable> tables = new ArrayList<>();
tables.add(new BulkTable(candidateTbl, true));
if (candidateTbl.getSuperDatastoreClass() != null) {
DatastoreClass tbl = candidateTbl;
while (tbl.getSuperDatastoreClass() != null) {
tbl = tbl.getSuperDatastoreClass();
tables.add(new BulkTable(tbl, false));
}
}
List<SQLStatement> stmts = new ArrayList<>();
List<Boolean> stmtCountFlags = new ArrayList<>();
for (BulkTable bulkTable : tables) {
// Generate statement for candidate
DatastoreClass table = bulkTable.table;
Map<String, Object> extensions = null;
if (!storeMgr.getDatastoreAdapter().supportsOption(DatastoreAdapter.UPDATE_DELETE_STATEMENT_ALLOW_TABLE_ALIAS_IN_WHERE_CLAUSE)) {
extensions = new HashMap<>();
extensions.put(SQLStatement.EXTENSION_SQL_TABLE_NAMING_STRATEGY, "table-name");
}
UpdateStatement stmt = new UpdateStatement(storeMgr, table, null, null, extensions);
stmt.setClassLoaderResolver(clr);
stmt.setCandidateClassName(candidateCmd.getFullClassName());
JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
if (multitenancyMapping != null) {
// Multi-tenancy restriction
SQLExpression tenantExpr = stmt.getSQLExpressionFactory().newExpression(stmt, stmt.getPrimaryTable(), multitenancyMapping);
SQLExpression tenantVal = stmt.getSQLExpressionFactory().newLiteral(stmt, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, candidateCmd));
stmt.whereAnd(tenantExpr.eq(tenantVal), true);
}
// TODO Discriminator restriction?
JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
if (softDeleteMapping != null) {
// Soft-delete restriction
SQLExpression softDeleteExpr = stmt.getSQLExpressionFactory().newExpression(stmt, stmt.getPrimaryTable(), softDeleteMapping);
SQLExpression softDeleteVal = stmt.getSQLExpressionFactory().newLiteral(stmt, softDeleteMapping, Boolean.FALSE);
stmt.whereAnd(softDeleteExpr.eq(softDeleteVal), true);
}
Set<String> options = new HashSet<>();
if (getBooleanExtensionProperty(EXTENSION_USE_IS_NULL_WHEN_EQUALS_NULL_PARAM, true)) {
options.add(QueryToSQLMapper.OPTION_NULL_PARAM_USE_IS_NULL);
}
QueryToSQLMapper sqlMapper = new QueryToSQLMapper(stmt, compilation, parameterValues, null, null, candidateCmd, subclasses, getFetchPlan(), ec, null, options, extensions);
setMapperJoinTypes(sqlMapper);
sqlMapper.compile();
if (stmt.hasUpdates()) {
stmts.add(stmt);
stmtCountFlags.add(bulkTable.useInCount);
datastoreCompilation.setStatementParameters(stmt.getSQLText().getParametersForStatement());
datastoreCompilation.setPrecompilable(sqlMapper.isPrecompilable());
}
}
datastoreCompilation.clearStatements();
Iterator<SQLStatement> stmtIter = stmts.iterator();
Iterator<Boolean> stmtCountFlagsIter = stmtCountFlags.iterator();
while (stmtIter.hasNext()) {
SQLStatement stmt = stmtIter.next();
Boolean useInCount = stmtCountFlagsIter.next();
if (stmts.size() == 1) {
useInCount = true;
}
datastoreCompilation.addStatement(stmt, stmt.getSQLText().toSQL(), useInCount);
}
}
use of org.datanucleus.store.rdbms.RDBMSStoreManager in project datanucleus-rdbms by datanucleus.
the class JDOQLQuery method compileQueryFull.
/**
* Method to set the (native) query statement for the compiled query as a whole.
* @param parameters Input parameters (if known)
* @param candidateCmd Metadata for the candidate class
*/
private void compileQueryFull(Map parameters, AbstractClassMetaData candidateCmd) {
if (type != QueryType.SELECT) {
return;
}
long startTime = 0;
if (NucleusLogger.QUERY.isDebugEnabled()) {
startTime = System.currentTimeMillis();
NucleusLogger.QUERY.debug(Localiser.msg("021083", getLanguage(), toString()));
}
if (result != null) {
datastoreCompilation.setResultDefinition(new StatementResultMapping());
} else {
datastoreCompilation.setResultDefinitionForClass(new StatementClassMapping());
}
// Generate statement for candidate(s)
SelectStatement stmt = null;
try {
boolean includeSoftDeletes = getBooleanExtensionProperty("include-soft-deletes", false);
Set<String> options = null;
if (includeSoftDeletes) {
options = new HashSet<>();
options.add(SelectStatementGenerator.OPTION_INCLUDE_SOFT_DELETES);
}
stmt = RDBMSQueryUtils.getStatementForCandidates((RDBMSStoreManager) getStoreManager(), null, candidateCmd, datastoreCompilation.getResultDefinitionForClass(), ec, candidateClass, subclasses, result, null, null, options);
} catch (NucleusException ne) {
// Statement would result in no results, so just catch it and avoid generating the statement
NucleusLogger.QUERY.warn("Query for candidates of " + candidateClass.getName() + (subclasses ? " and subclasses" : "") + " resulted in no possible candidates : " + StringUtils.getMessageFromRootCauseOfThrowable(ne));
statementReturnsEmpty = true;
return;
}
// Update the SQLStatement with filter, ordering, result etc
Set<String> options = new HashSet<>();
options.add(QueryToSQLMapper.OPTION_BULK_UPDATE_VERSION);
if (getBooleanExtensionProperty(EXTENSION_USE_IS_NULL_WHEN_EQUALS_NULL_PARAM, true)) {
options.add(QueryToSQLMapper.OPTION_NULL_PARAM_USE_IS_NULL);
}
if (getBooleanExtensionProperty(EXTENSION_NON_DISTINCT_IMPLICIT_JOIN, false)) {
options.add(QueryToSQLMapper.OPTION_NON_DISTINCT_IMPLICIT_JOINS);
}
QueryToSQLMapper sqlMapper = new QueryToSQLMapper(stmt, compilation, parameters, datastoreCompilation.getResultDefinitionForClass(), datastoreCompilation.getResultDefinition(), candidateCmd, subclasses, getFetchPlan(), ec, getParsedImports(), options, extensions);
setMapperJoinTypes(sqlMapper);
sqlMapper.compile();
datastoreCompilation.setParameterNameByPosition(sqlMapper.getParameterNameByPosition());
datastoreCompilation.setPrecompilable(sqlMapper.isPrecompilable());
if (!getResultDistinct() && stmt.isDistinct()) {
setResultDistinct(true);
compilation.setResultDistinct();
}
if (candidateCollection != null) {
// Restrict to the supplied candidate ids
BooleanExpression candidateExpr = null;
Iterator iter = candidateCollection.iterator();
JavaTypeMapping idMapping = stmt.getPrimaryTable().getTable().getIdMapping();
while (iter.hasNext()) {
Object candidate = iter.next();
SQLExpression idExpr = stmt.getSQLExpressionFactory().newExpression(stmt, stmt.getPrimaryTable(), idMapping);
SQLExpression idVal = stmt.getSQLExpressionFactory().newLiteral(stmt, idMapping, candidate);
if (candidateExpr == null) {
candidateExpr = idExpr.eq(idVal);
} else {
candidateExpr = candidateExpr.ior(idExpr.eq(idVal));
}
}
stmt.whereAnd(candidateExpr, true);
}
// Apply any range
if (range != null) {
long lower = fromInclNo;
long upper = toExclNo;
if (fromInclParam != null) {
if (parameters.containsKey(fromInclParam)) {
lower = ((Number) parameters.get(fromInclParam)).longValue();
} else {
// Must be numbered input so take penultimate
lower = ((Number) parameters.get(Integer.valueOf(parameters.size() - 2))).longValue();
}
}
if (toExclParam != null) {
if (parameters.containsKey(toExclParam)) {
upper = ((Number) parameters.get(toExclParam)).longValue();
} else {
// Must be numbered input so take ultimate
upper = ((Number) parameters.get(Integer.valueOf(parameters.size() - 1))).longValue();
}
}
stmt.setRange(lower, upper - lower);
}
// Set any extensions
boolean useUpdateLock = RDBMSQueryUtils.useUpdateLockForQuery(this);
stmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, Boolean.valueOf(useUpdateLock));
if (getBooleanExtensionProperty(EXTENSION_FOR_UPDATE_NOWAIT, false)) {
stmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE_NOWAIT, Boolean.TRUE);
}
datastoreCompilation.addStatement(stmt, stmt.getSQLText().toSQL(), false);
datastoreCompilation.setStatementParameters(stmt.getSQLText().getParametersForStatement());
if (result == null && !(resultClass != null && resultClass != candidateClass)) {
// Select of candidates, so check for any immediate multi-valued fields that are marked for fetching
// TODO If the query joins to a 1-1/N-1 and then we have a multi-valued field, we should allow that too
FetchPlanForClass fpc = getFetchPlan().getFetchPlanForClass(candidateCmd);
int[] fpMembers = fpc.getMemberNumbers();
for (int i = 0; i < fpMembers.length; i++) {
AbstractMemberMetaData fpMmd = candidateCmd.getMetaDataForManagedMemberAtAbsolutePosition(fpMembers[i]);
RelationType fpRelType = fpMmd.getRelationType(clr);
if (RelationType.isRelationMultiValued(fpRelType)) {
if (fpMmd.hasCollection() && SCOUtils.collectionHasSerialisedElements(fpMmd)) {
// Ignore collections serialised into the owner (retrieved in main query)
} else if (fpMmd.hasMap() && SCOUtils.mapHasSerialisedKeysAndValues(fpMmd)) {
// Ignore maps serialised into the owner (retrieved in main query)
} else if (fpMmd.hasMap()) {
// Ignore maps for now until we support them
} else {
String multifetchType = getStringExtensionProperty(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH, null);
if (multifetchType == null) {
// Default to bulk-fetch EXISTS, so advise the user of why this is happening and how to turn it off
NucleusLogger.QUERY.debug("You have selected field " + fpMmd.getFullFieldName() + " for fetching by this query. We will fetch it using 'EXISTS'." + " To disable this set the query extension/hint '" + RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH + "' as 'none' or remove the field" + " from the query FetchPlan. If this bulk-fetch generates an invalid or unoptimised query, please report it with a way of reproducing it");
multifetchType = "exists";
}
if (multifetchType.equalsIgnoreCase("exists")) {
// Fetch container contents for all candidate owners
BulkFetchExistsHandler helper = new BulkFetchExistsHandler();
IteratorStatement iterStmt = helper.getStatementToBulkFetchField(candidateCmd, fpMmd, this, parameters, datastoreCompilation, options);
if (iterStmt != null) {
datastoreCompilation.setSCOIteratorStatement(fpMmd.getFullFieldName(), iterStmt);
} else {
NucleusLogger.GENERAL.debug("Note that query has field " + fpMmd.getFullFieldName() + " marked in the FetchPlan, yet this is currently not fetched by this query");
}
} else if (multifetchType.equalsIgnoreCase("join")) {
// Fetch container contents for all candidate owners
BulkFetchJoinHandler helper = new BulkFetchJoinHandler();
IteratorStatement iterStmt = helper.getStatementToBulkFetchField(candidateCmd, fpMmd, this, parameters, datastoreCompilation, options);
if (iterStmt != null) {
datastoreCompilation.setSCOIteratorStatement(fpMmd.getFullFieldName(), iterStmt);
} else {
NucleusLogger.GENERAL.debug("Note that query has field " + fpMmd.getFullFieldName() + " marked in the FetchPlan, yet this is currently not fetched by this query");
}
} else {
NucleusLogger.GENERAL.debug("Note that query has field " + fpMmd.getFullFieldName() + " marked in the FetchPlan, yet this is not fetched by this query.");
}
// TODO Continue this bulk fetch process to multivalued fields of this field
}
} else if (RelationType.isRelationSingleValued(fpRelType)) {
// TODO Check for multivalued fields of this 1-1/N-1 field
}
}
}
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug(Localiser.msg("021084", getLanguage(), System.currentTimeMillis() - startTime));
}
}
use of org.datanucleus.store.rdbms.RDBMSStoreManager in project datanucleus-rdbms by datanucleus.
the class JDOQLQuery method processesRangeInDatastoreQuery.
/* (non-Javadoc)
* @see org.datanucleus.store.query.Query#processesRangeInDatastoreQuery()
*/
@Override
public boolean processesRangeInDatastoreQuery() {
if (range == null) {
// No range specified so makes no difference
return true;
}
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
DatastoreAdapter dba = storeMgr.getDatastoreAdapter();
boolean using_limit_where_clause = (dba.getRangeByLimitEndOfStatementClause(fromInclNo, toExclNo, !StringUtils.isWhitespace(ordering)).length() > 0);
boolean using_rownum = (dba.getRangeByRowNumberColumn().length() > 0) || (dba.getRangeByRowNumberColumn2().length() > 0);
return using_limit_where_clause || using_rownum;
}
use of org.datanucleus.store.rdbms.RDBMSStoreManager in project datanucleus-rdbms by datanucleus.
the class JPQLQuery method compileQueryInsert.
/**
* Method to compile the query for RDBMS for a bulk INSERT.
* @param parameterValues The parameter values (if any)
* @param candidateCmd Meta-data for the candidate class
*/
protected void compileQueryInsert(Map parameterValues, AbstractClassMetaData candidateCmd) {
if (StringUtils.isWhitespace(insertFields) || StringUtils.isWhitespace(insertSelectQuery)) {
// Nothing to INSERT
return;
}
List<String> fieldNames = new ArrayList<>();
StringTokenizer fieldTokenizer = new StringTokenizer(insertFields, ",");
while (fieldTokenizer.hasMoreTokens()) {
String token = fieldTokenizer.nextToken().trim();
fieldNames.add(token);
}
// Generate statement for candidate and related classes in this inheritance tree
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
DatastoreClass candidateTbl = storeMgr.getDatastoreClass(candidateCmd.getFullClassName(), clr);
if (candidateTbl == null) {
// TODO Using subclass-table, so find the table(s) it can be persisted into
throw new NucleusDataStoreException("Bulk INSERT of " + candidateCmd.getFullClassName() + " not supported since candidate has no table of its own");
}
// Find table(s) that need populating with this information
List<BulkTable> tables = new ArrayList<>();
tables.add(new BulkTable(candidateTbl, true));
if (candidateTbl.getSuperDatastoreClass() != null) {
DatastoreClass tbl = candidateTbl;
while (tbl.getSuperDatastoreClass() != null) {
tbl = tbl.getSuperDatastoreClass();
tables.add(0, new BulkTable(tbl, false));
}
}
if (tables.size() > 1) {
throw new NucleusUserException("BULK INSERT only currently allows a single table, but this query implies INSERT into " + tables.size() + " tables!");
}
List<SQLStatement> stmts = new ArrayList<>();
List<Boolean> stmtCountFlags = new ArrayList<>();
for (BulkTable bulkTable : tables) {
// Generate statement for candidate
InsertStatement stmt = new InsertStatement(storeMgr, bulkTable.table, null, null, null);
stmt.setClassLoaderResolver(clr);
stmt.setCandidateClassName(candidateCmd.getFullClassName());
// Set columns for this table
for (String fieldName : fieldNames) {
AbstractMemberMetaData fieldMmd = candidateCmd.getMetaDataForMember(fieldName);
if (fieldMmd == null) {
// No such field
} else {
JavaTypeMapping fieldMapping = bulkTable.table.getMemberMapping(fieldMmd);
if (fieldMapping != null) {
SQLExpression fieldExpr = stmt.getSQLExpressionFactory().newExpression(stmt, stmt.getPrimaryTable(), fieldMapping);
for (int i = 0; i < fieldExpr.getNumberOfSubExpressions(); i++) {
ColumnExpression fieldColExpr = fieldExpr.getSubExpression(i);
fieldColExpr.setOmitTableFromString(true);
}
stmt.addColumn(fieldExpr);
} else {
// Not in this table
}
}
}
// Generate the select query and add it to the InsertStatement
JPQLQuery selectQuery = new JPQLQuery(storeMgr, ec, insertSelectQuery);
selectQuery.compile();
stmt.setSelectStatement((SelectStatement) selectQuery.getDatastoreCompilation().getStatementCompilations().get(0).getStatement());
selectQuery.closeAll();
// TODO if we have multiple tables then this will mean only using some of the columns in the selectSQL
stmts.add(stmt);
stmtCountFlags.add(bulkTable.useInCount);
datastoreCompilation.setStatementParameters(stmt.getSQLText().getParametersForStatement());
}
datastoreCompilation.clearStatements();
Iterator<SQLStatement> stmtIter = stmts.iterator();
Iterator<Boolean> stmtCountFlagsIter = stmtCountFlags.iterator();
while (stmtIter.hasNext()) {
SQLStatement stmt = stmtIter.next();
Boolean useInCount = stmtCountFlagsIter.next();
if (stmts.size() == 1) {
useInCount = true;
}
datastoreCompilation.addStatement(stmt, stmt.getSQLText().toSQL(), useInCount);
}
}
use of org.datanucleus.store.rdbms.RDBMSStoreManager in project datanucleus-rdbms by datanucleus.
the class JPQLQuery method compileInternal.
/**
* Method to compile the JPQL query.
* Uses the superclass to compile the generic query populating the "compilation", and then generates
* the datastore-specific "datastoreCompilation".
* @param parameterValues Map of param values keyed by param name (if available at compile time)
*/
protected synchronized void compileInternal(Map parameterValues) {
if (isCompiled()) {
return;
}
// Compile the generic query expressions
super.compileInternal(parameterValues);
boolean inMemory = evaluateInMemory();
if (candidateCollection != null) {
// TODO Maybe apply the result class checks ?
return;
}
if (candidateClass == null || candidateClassName == null) {
candidateClass = compilation.getCandidateClass();
candidateClassName = candidateClass.getName();
}
// Create the SQL statement, and its result/parameter definitions
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
QueryManager qm = getQueryManager();
String datastoreKey = storeMgr.getQueryCacheKey();
String queryCacheKey = getQueryCacheKey();
if (useCaching() && queryCacheKey != null) {
// Check if we have any parameters set to null, since this can invalidate a datastore compilation
// e.g " field == :val" can be "COL IS NULL" or "COL = <val>"
boolean nullParameter = false;
if (parameterValues != null) {
Iterator iter = parameterValues.values().iterator();
while (iter.hasNext()) {
Object val = iter.next();
if (val == null) {
nullParameter = true;
break;
}
}
}
if (!nullParameter) {
// Allowing caching so try to find compiled (datastore) query
datastoreCompilation = (RDBMSQueryCompilation) qm.getDatastoreQueryCompilation(datastoreKey, getLanguage(), queryCacheKey);
if (datastoreCompilation != null) {
// Cached compilation exists for this datastore so reuse it
return;
}
}
}
// No cached compilation for this query in this datastore so compile it
AbstractClassMetaData acmd = getCandidateClassMetaData();
if (type == QueryType.BULK_INSERT) {
datastoreCompilation = new RDBMSQueryCompilation();
compileQueryInsert(parameterValues, acmd);
} else if (type == QueryType.BULK_UPDATE) {
datastoreCompilation = new RDBMSQueryCompilation();
compileQueryUpdate(parameterValues, acmd);
} else if (type == QueryType.BULK_DELETE) {
datastoreCompilation = new RDBMSQueryCompilation();
compileQueryDelete(parameterValues, acmd);
} else {
datastoreCompilation = new RDBMSQueryCompilation();
if (inMemory) {
// Generate statement to just retrieve all candidate objects for later processing
compileQueryToRetrieveCandidates(parameterValues, acmd);
} else {
// Generate statement to perform the full query in the datastore
compileQueryFull(parameterValues, acmd);
if (result != null) {
StatementResultMapping resultMapping = datastoreCompilation.getResultDefinition();
for (int i = 0; i < resultMapping.getNumberOfResultExpressions(); i++) {
Object stmtMap = resultMapping.getMappingForResultExpression(i);
if (stmtMap instanceof StatementMappingIndex) {
StatementMappingIndex idx = (StatementMappingIndex) stmtMap;
AbstractMemberMetaData mmd = idx.getMapping().getMemberMetaData();
if (mmd != null) {
if (idx.getMapping() instanceof AbstractContainerMapping && idx.getMapping().getNumberOfDatastoreMappings() != 1) {
throw new NucleusUserException(Localiser.msg("021213"));
}
}
}
}
}
}
if (resultClass != null && result != null) {
// Do as PrivilegedAction since uses reflection
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
// Check that this class has the necessary constructor/setters/fields to be used
StatementResultMapping resultMapping = datastoreCompilation.getResultDefinition();
if (QueryUtils.resultClassIsSimple(resultClass.getName())) {
if (resultMapping.getNumberOfResultExpressions() > 1) {
// Invalid number of result expressions
throw new NucleusUserException(Localiser.msg("021201", resultClass.getName()));
}
Object stmtMap = resultMapping.getMappingForResultExpression(0);
// TODO Handle StatementNewObjectMapping
StatementMappingIndex idx = (StatementMappingIndex) stmtMap;
Class exprType = idx.getMapping().getJavaType();
boolean typeConsistent = false;
if (exprType == resultClass) {
typeConsistent = true;
} else if (exprType.isPrimitive()) {
Class resultClassPrimitive = ClassUtils.getPrimitiveTypeForType(resultClass);
if (resultClassPrimitive == exprType) {
typeConsistent = true;
}
}
if (!typeConsistent) {
// Inconsistent expression type not matching the result class type
throw new NucleusUserException(Localiser.msg("021202", resultClass.getName(), exprType));
}
} else if (QueryUtils.resultClassIsUserType(resultClass.getName())) {
// Check for valid constructor (either using param types, or using default ctr)
Class[] ctrTypes = new Class[resultMapping.getNumberOfResultExpressions()];
for (int i = 0; i < ctrTypes.length; i++) {
Object stmtMap = resultMapping.getMappingForResultExpression(i);
if (stmtMap instanceof StatementMappingIndex) {
ctrTypes[i] = ((StatementMappingIndex) stmtMap).getMapping().getJavaType();
} else if (stmtMap instanceof StatementNewObjectMapping) {
// TODO Handle this
}
}
Constructor ctr = ClassUtils.getConstructorWithArguments(resultClass, ctrTypes);
if (ctr == null && !ClassUtils.hasDefaultConstructor(resultClass)) {
// No valid constructor found!
throw new NucleusUserException(Localiser.msg("021205", resultClass.getName()));
} else if (ctr == null) {
// We are using default constructor, so check the types of the result expressions for means of input
for (int i = 0; i < resultMapping.getNumberOfResultExpressions(); i++) {
Object stmtMap = resultMapping.getMappingForResultExpression(i);
if (stmtMap instanceof StatementMappingIndex) {
StatementMappingIndex mapIdx = (StatementMappingIndex) stmtMap;
AbstractMemberMetaData mmd = mapIdx.getMapping().getMemberMetaData();
String fieldName = mapIdx.getColumnAlias();
Class fieldType = mapIdx.getMapping().getJavaType();
if (fieldName == null && mmd != null) {
fieldName = mmd.getName();
}
if (fieldName != null) {
// Check for the field of that name in the result class
Class resultFieldType = null;
boolean publicField = true;
try {
Field fld = resultClass.getDeclaredField(fieldName);
resultFieldType = fld.getType();
// Check the type of the field
if (!ClassUtils.typesAreCompatible(fieldType, resultFieldType) && !ClassUtils.typesAreCompatible(resultFieldType, fieldType)) {
throw new NucleusUserException(Localiser.msg("021211", fieldName, fieldType.getName(), resultFieldType.getName()));
}
if (!Modifier.isPublic(fld.getModifiers())) {
publicField = false;
}
} catch (NoSuchFieldException nsfe) {
publicField = false;
}
// Check for a public set method
if (!publicField) {
Method setMethod = QueryUtils.getPublicSetMethodForFieldOfResultClass(resultClass, fieldName, resultFieldType);
if (setMethod == null) {
// No setter, so check for a public put(Object, Object) method
Method putMethod = QueryUtils.getPublicPutMethodForResultClass(resultClass);
if (putMethod == null) {
throw new NucleusUserException(Localiser.msg("021212", resultClass.getName(), fieldName));
}
}
}
}
} else if (stmtMap instanceof StatementNewObjectMapping) {
// TODO Handle this
}
}
}
}
return null;
}
});
}
boolean hasParams = false;
if (explicitParameters != null) {
hasParams = true;
} else if (parameterValues != null && parameterValues.size() > 0) {
hasParams = true;
}
if (!datastoreCompilation.isPrecompilable() || (datastoreCompilation.getSQL().indexOf('?') < 0 && hasParams)) {
// Some parameters had their clauses evaluated during compilation so the query didn't gain any parameters, so don't cache it
NucleusLogger.QUERY.debug(Localiser.msg("021075"));
} else {
if (useCaching() && queryCacheKey != null) {
qm.addDatastoreQueryCompilation(datastoreKey, getLanguage(), queryCacheKey, datastoreCompilation);
}
}
}
}
Aggregations