protected function validateMappings($mappings, $allowAssociations)
    {
        $type = null;
        foreach ($mappings as $mapping) {
            //compatible date or number types are identical for our purposes here
            switch ($mapping->type) {
                case Type::TIMESTAMP:
                    $thisType = Type::DATE;
                    break;
                case Type::FLOAT:
                    $thisType = Type::INT;
                    break;
                default:
                    if (!$mapping->isAssociation()) {
                        $thisType = $mapping->type;
                        break;
                    }

                    if (!$allowAssociations) {
                        throw ODMException::queryOperatorAssociationsNotSupported(static::class);
                    }

                    if ($mapping->isMany()) {
                        if (!isset($collectionType)) {
                            $collectionType = $mapping->type;
                        } elseif ($collectionType !== $mapping->type) {
                            throw ODMException::queryIncompatibleTypes();
                        }
                    }

                    $thisType = $mapping->association;

                    if (!$mapping->reference) {
                        //embedded documents are serialized according to their class's
                        //mapping - irrespective of any association mapping options -
                        //so no further validation is required here
                        break;
                    }

                    //reference serialization depends on storeAs, targetDocument,
                    //and discriminator options.

                    if (!isset($storeAs)) {
                        $storeAs = $mapping->storeAs;
                    } elseif ($storeAs !== $mapping->storeAs) {
                        throw ODMException::queryIncompatibleTypes();
                    }

                    if (!isset($targetDoc)) {
                        $targetDoc = $mapping->targetDocument;
                    } elseif ($targetDoc !== $mapping->targetDocument) {
                        throw ODMException::queryIncompatibleTypes();
                    }

                    if ($targetDoc !== null) {
                        break;
                    }

                    if (!isset($discriminatorAttribute)) {
                        $discriminatorAttribute = $mapping->discriminatorAttribute;
                    } elseif ($discriminatorAttribute !== $mapping->discriminatorAttribute) {
                        throw ODMException::queryIncompatibleTypes();
                    }

                    if (!isset($discriminatorDefaultValue)) {
                        $discriminatorDefaultValue = $mapping->discriminatorDefaultValue;
                    } elseif ($discriminatorDefaultValue !== $mapping->discriminatorDefaultValue) {
                        throw ODMException::queryIncompatibleTypes();
                    }

                    if (!isset($discriminatorMap)) {
                        $discriminatorMap = $mapping->discriminatorMap;
                    } elseif ($discriminatorMap !== $mapping->discriminatorMap) {
                        throw ODMException::queryIncompatibleTypes();
                    }
            }

            if ($type === null) {
                $type = $thisType;
            } elseif ($thisType !== $type) {
                throw ODMException::queryIncompatibleTypes();
            }
        }
    }