/** INTERNAL: Transform the object-level value into a database-level value */ public Object getFieldValue(Object objectValue, AbstractSession session) { DatabaseMapping mapping = getMapping(); Object fieldValue = objectValue; if ((mapping != null) && (mapping.isDirectToFieldMapping() || mapping.isDirectCollectionMapping())) { // CR#3623207, check for IN Collection here not in mapping. if (objectValue instanceof Collection) { // This can actually be a collection for IN within expressions... however it would be better // for expressions to handle this. Collection values = (Collection) objectValue; Vector fieldValues = new Vector(values.size()); for (Iterator iterator = values.iterator(); iterator.hasNext(); ) { Object value = iterator.next(); if (!(value instanceof Expression)) { value = getFieldValue(value, session); } fieldValues.add(value); } fieldValue = fieldValues; } else { if (mapping.isDirectToFieldMapping()) { fieldValue = ((AbstractDirectMapping) mapping).getFieldValue(objectValue, session); } else if (mapping.isDirectCollectionMapping()) { fieldValue = ((DirectCollectionMapping) mapping).getFieldValue(objectValue, session); } } } return fieldValue; }
// operation should be either INSERT or UPDATE protected void trimModifyRow(AbstractRecord modifyRow, int operation) { if ((modifyRow == null) || modifyRow.isEmpty()) { return; } Collection fields = main[operation][RETURN_ONLY]; if ((fields == null) || fields.isEmpty()) { return; } for (int i = modifyRow.size() - 1; i >= 0; i--) { DatabaseField field = modifyRow.getFields().get(i); if (fields.contains(field)) { modifyRow.remove(field); } } }
protected void addCollectionToMain(int operation, int state, Collection collection) { if ((collection == null) || collection.isEmpty()) { return; } if (main[operation][state] == null) { main[operation][state] = createCollection(); } main[operation][state].addAll(collection); }
/** * INTERNAL: Execute the query. If there are cached results return those. This must override the * super to support result caching. * * @param session - the session in which the receiver will be executed. * @return An object or vector, the result of executing the query. * @exception DatabaseException - an error has occurred on the database */ public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException { if (shouldCacheQueryResults()) { if (getContainerPolicy().overridesRead()) { throw QueryException.cannotCacheCursorResultsOnQuery(this); } if (shouldConformResultsInUnitOfWork()) { throw QueryException.cannotConformAndCacheQueryResults(this); } if (isPrepared()) { // only prepared queries can have cached results. Object queryResults = getQueryResults(session, row, true); if (queryResults != null) { if (QueryMonitor.shouldMonitor()) { QueryMonitor.incrementReadAllHits(this); } // bug6138532 - check for "cached no results" (InvalidObject singleton) in query // results, and return an empty container instance as configured if (queryResults == InvalidObject.instance) { return getContainerPolicy().containerInstance(0); } Collection results = (Collection) queryResults; if (session.isUnitOfWork()) { ContainerPolicy policy = getContainerPolicy(); Object resultCollection = policy.containerInstance(results.size()); Object iterator = policy.iteratorFor(results); while (policy.hasNext(iterator)) { Object result = ((UnitOfWorkImpl) session) .registerExistingObject(policy.next(iterator, session), this.descriptor); policy.addInto(result, resultCollection, session); } return resultCollection; } return results; } } } if (QueryMonitor.shouldMonitor()) { QueryMonitor.incrementReadAllMisses(this); } return super.execute(session, row); }
/** * INTERNAL: Compares two Collections as sets (ignoring the order of the elements). Note that the * passed Collections are cloned. Used for testing only. */ public static boolean areCollectionsEqualAsSets(Collection col1, Collection col2) { if (col1 == col2) { return true; } if (col1.size() != col2.size()) { return false; } Collection c1 = new ArrayList(col1); Collection c2 = new ArrayList(col2); for (Iterator i = c1.iterator(); i.hasNext(); ) { Object o = i.next(); c2.remove(o); } return c2.isEmpty(); }
/** INTERNAL: */ public void validationAfterDescriptorInitialization(AbstractSession session) { Hashtable mapped = new Hashtable(); for (int operation = INSERT; operation <= UPDATE; operation++) { if ((main[operation][MAPPED] != null) && !main[operation][MAPPED].isEmpty()) { Iterator it = main[operation][MAPPED].iterator(); while (it.hasNext()) { DatabaseField field = (DatabaseField) it.next(); mapped.put(field, field); } } } if (!mapped.isEmpty()) { for (Enumeration fields = getDescriptor().getFields().elements(); fields.hasMoreElements(); ) { DatabaseField fieldInDescriptor = (DatabaseField) fields.nextElement(); DatabaseField fieldInMain = (DatabaseField) mapped.get(fieldInDescriptor); if (fieldInMain != null) { if (fieldInMain.getType() == null) { if (getDescriptor().isReturnTypeRequiredForReturningPolicy()) { session .getIntegrityChecker() .handleError( DescriptorException.returningPolicyMappedFieldTypeNotSet( fieldInMain.getName(), getDescriptor())); } } else if (isThereATypeConflict(fieldInMain, fieldInDescriptor)) { session .getIntegrityChecker() .handleError( DescriptorException.returningPolicyAndDescriptorFieldTypeConflict( fieldInMain.getName(), fieldInMain.getType().getName(), fieldInDescriptor.getType().getName(), getDescriptor())); } } } } if (!(session.getDatasourcePlatform() instanceof DatabasePlatform)) { // don't attempt further diagnostics on non-relational platforms return; } WriteObjectQuery[] query = { getDescriptor().getQueryManager().getInsertQuery(), getDescriptor().getQueryManager().getUpdateQuery() }; String[] queryTypeName = {"InsertObjectQuery", "UpdateObjectQuery"}; for (int operation = INSERT; operation <= UPDATE; operation++) { if ((main[operation][ALL] != null) && !main[operation][ALL].isEmpty()) { // this operation requires some fields to be returned if ((query[operation] == null) || (query[operation].getDatasourceCall() == null)) { if (!session.getPlatform().canBuildCallWithReturning()) { session .getIntegrityChecker() .handleError( DescriptorException.noCustomQueryForReturningPolicy( queryTypeName[operation], Helper.getShortClassName(session.getPlatform()), getDescriptor())); } } else if (query[operation].getDatasourceCall() instanceof StoredProcedureCall) { // SQLCall with custom SQL calculates its outputRowFields later (in prepare() method) - // that's why SQLCall can't be verified here. DatabaseCall customCall = (DatabaseCall) query[operation].getDatasourceCall(); Enumeration outputRowFields = customCall.getOutputRowFields().elements(); Collection notFoundInOutputRow = createCollection(); notFoundInOutputRow.addAll(main[operation][ALL]); while (outputRowFields.hasMoreElements()) { notFoundInOutputRow.remove(outputRowFields.nextElement()); } if (!notFoundInOutputRow.isEmpty()) { Iterator it = notFoundInOutputRow.iterator(); while (it.hasNext()) { DatabaseField field = (DatabaseField) it.next(); session .getIntegrityChecker() .handleError( DescriptorException.customQueryAndReturningPolicyFieldConflict( field.getName(), queryTypeName[operation], getDescriptor())); } } } } } }