public function setComponent($componentName, $item)
    {
        // Validate component
        $schema = static::getSchema();
        if ($class = $schema->hasOneComponent(static::class, $componentName)) {
            // Force item to be written if not by this point
            // @todo This could be lazy-written in a beforeWrite hook, but force write here for simplicity
            // https://github.com/silverstripe/silverstripe-framework/issues/7818
            if ($item && !$item->isInDB()) {
                $item->write();
            }

            // Update local ID
            $joinField = $componentName . 'ID';
            $this->setField($joinField, $item ? $item->ID : null);
            // Update Class (Polymorphic has_one)
            // Extract class name for polymorphic relations
            if ($class === self::class) {
                $this->setField($componentName . 'Class', $item ? get_class($item) : null);
            }
        } elseif ($class = $schema->belongsToComponent(static::class, $componentName)) {
            if ($item) {
                // For belongs_to, add to has_one on other component
                $joinField = $schema->getRemoteJoinField(static::class, $componentName, 'belongs_to', $polymorphic);
                if (!$polymorphic) {
                    $joinField = substr($joinField, 0, -2);
                }
                $item->setComponent($joinField, $this);
            }
        } else {
            throw new InvalidArgumentException(
                "DataObject->setComponent(): Could not find component '$componentName'."
            );
        }

        $this->components[$componentName] = $item;
        return $this;
    }