diff --git a/typo3/sysext/backend/Classes/Preview/FluidBasedContentPreviewRenderer.php b/typo3/sysext/backend/Classes/Preview/FluidBasedContentPreviewRenderer.php
index 9b810638a9236dac7a8fd51ccf2674938220e513..2c698e759b87c14eafcb6785766daaa5be9ad2ca 100644
--- a/typo3/sysext/backend/Classes/Preview/FluidBasedContentPreviewRenderer.php
+++ b/typo3/sysext/backend/Classes/Preview/FluidBasedContentPreviewRenderer.php
@@ -93,6 +93,7 @@ final readonly class FluidBasedContentPreviewRenderer
             if ($table === 'tt_content' && !empty($row['pi_flexform'])) {
                 $view->assign('pi_flexform_transformed', $this->flexFormService->convertFlexFormContentToArray($row['pi_flexform']));
             }
+            // @todo Should we make sure that "record" is actually a Record object?
             $view->assign('record', $this->recordFactory->createResolvedRecordFromDatabaseRow($table, $row));
             return $view->render();
         } catch (\Exception $e) {
diff --git a/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php b/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php
index 9338a6022dd1011b787357e252a5ceb111852e38..b6f5b1e76b4dd2a41c38df8a64382fc39dbe086d 100644
--- a/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php
+++ b/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php
@@ -115,17 +115,19 @@ class StandardContentPreviewRenderer implements PreviewRendererInterface, Logger
             case 'header':
                 break;
             case 'uploads':
-                if ($recordObj['media'] ?? false) {
-                    $out .= $this->linkEditContent($this->getThumbCodeUnlinked($recordObj['media']), $record);
+                if ($recordObj->has('media') && ($media = $recordObj->get('media'))) {
+                    $out .= $this->linkEditContent($this->getThumbCodeUnlinked($media), $record);
                 }
                 break;
             case 'shortcut':
-                if (!empty($recordObj['records'])) {
+                if ($recordObj->has('records') && ($records = $recordObj->get('records'))) {
                     $shortcutContent = '';
-                    $shortcutRecords = $recordObj['records'] instanceof \Traversable ? $recordObj['records'] : [$recordObj['records']];
+                    $shortcutRecords = $records instanceof \Traversable ? $records : [$records];
                     foreach ($shortcutRecords as $shortcutRecord) {
                         $shortcutTableName = $shortcutRecord->getMainType();
-                        $shortcutRecord = $this->translateShortcutRecord($recordObj, $shortcutRecord, $shortcutTableName);
+                        if ($recordObj instanceof Record) {
+                            $shortcutRecord = $this->translateShortcutRecord($recordObj, $shortcutRecord, $shortcutTableName);
+                        }
                         $icon = $this->getIconFactory()->getIconForRecord($shortcutTableName, $shortcutRecord->toArray(), IconSize::SMALL)->render();
                         $icon = BackendUtility::wrapClickMenuOnIcon(
                             $icon,
@@ -168,17 +170,17 @@ class StandardContentPreviewRenderer implements PreviewRendererInterface, Logger
                 }
                 break;
             default:
-                if ($recordObj['bodytext'] ?? false) {
-                    $out .= $this->linkEditContent($this->renderText($record['bodytext']), $record);
+                if ($recordObj->has('bodytext') && ($bodytext = $recordObj->get('bodytext'))) {
+                    $out .= $this->linkEditContent($this->renderText($bodytext), $record);
                 }
-                if ($recordObj['image'] ?? false) {
-                    $out .= $this->linkEditContent($this->getThumbCodeUnlinked($recordObj['image']), $record);
+                if ($recordObj->has('image') && ($image = $recordObj->get('image'))) {
+                    $out .= $this->linkEditContent($this->getThumbCodeUnlinked($image), $record);
                 }
-                if ($recordObj['media'] ?? false) {
-                    $out .= $this->linkEditContent($this->getThumbCodeUnlinked($recordObj['media']), $record);
+                if ($recordObj->has('media') && ($media = $recordObj->get('media'))) {
+                    $out .= $this->linkEditContent($this->getThumbCodeUnlinked($media), $record);
                 }
-                if ($recordObj['assets'] ?? false) {
-                    $out .= $this->linkEditContent($this->getThumbCodeUnlinked($recordObj['assets']), $record);
+                if ($recordObj->has('assets') && ($assets = $recordObj->get('assets'))) {
+                    $out .= $this->linkEditContent($this->getThumbCodeUnlinked($assets), $record);
                 }
         }
 
diff --git a/typo3/sysext/core/Classes/DataHandling/RecordFieldTransformer.php b/typo3/sysext/core/Classes/DataHandling/RecordFieldTransformer.php
index 09cfc3afc793e6c12be2da2d8414b810acc5c720..40175c70727baf7dda36319755694e8fec9ff1ec 100644
--- a/typo3/sysext/core/Classes/DataHandling/RecordFieldTransformer.php
+++ b/typo3/sysext/core/Classes/DataHandling/RecordFieldTransformer.php
@@ -84,7 +84,7 @@ readonly class RecordFieldTransformer
 
     public function transformField(FieldTypeInterface $fieldInformation, RawRecord $rawRecord, Context $context): mixed
     {
-        $fieldValue = $rawRecord[$fieldInformation->getName()];
+        $fieldValue = $rawRecord->get($fieldInformation->getName());
 
         // type=file needs to be handled before RelationalFieldTypeInterface
         if ($fieldInformation instanceof FileFieldType) {
diff --git a/typo3/sysext/core/Classes/Domain/Exception/IncompleteRecordException.php b/typo3/sysext/core/Classes/Domain/Exception/IncompleteRecordException.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2f384725bb4598e36ce48e32b94e17a91f9673a
--- /dev/null
+++ b/typo3/sysext/core/Classes/Domain/Exception/IncompleteRecordException.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Core\Domain\Exception;
+
+use TYPO3\CMS\Core\Exception;
+
+/**
+ * @internal
+ */
+class IncompleteRecordException extends Exception {}
diff --git a/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyException.php b/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyException.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ddfe64e121cb90ea2f8511e09969bf03c0a4e9a
--- /dev/null
+++ b/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyException.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Core\Domain\Exception;
+
+use Psr\Container\ContainerExceptionInterface;
+use TYPO3\CMS\Core\Exception;
+
+/**
+ * @internal
+ */
+class RecordPropertyException extends Exception implements ContainerExceptionInterface {}
diff --git a/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyNotFoundException.php b/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyNotFoundException.php
new file mode 100644
index 0000000000000000000000000000000000000000..4bbe0628e7ffb76786646f8130746b97861497bd
--- /dev/null
+++ b/typo3/sysext/core/Classes/Domain/Exception/RecordPropertyNotFoundException.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Core\Domain\Exception;
+
+use Psr\Container\NotFoundExceptionInterface;
+use TYPO3\CMS\Core\Exception;
+
+/**
+ * @internal
+ */
+class RecordPropertyNotFoundException extends Exception implements NotFoundExceptionInterface {}
diff --git a/typo3/sysext/core/Classes/Domain/RawRecord.php b/typo3/sysext/core/Classes/Domain/RawRecord.php
index 2acb42c89d73fdd071018d8fa08a1c60557a14f3..3f3287b5e61a27eddc256b288275e12c219277ab 100644
--- a/typo3/sysext/core/Classes/Domain/RawRecord.php
+++ b/typo3/sysext/core/Classes/Domain/RawRecord.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Domain;
 
+use TYPO3\CMS\Core\Domain\Exception\RecordPropertyNotFoundException;
 use TYPO3\CMS\Core\Domain\Record\ComputedProperties;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -25,7 +26,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  *
  * @internal not part of public API, as this needs to be streamlined and proven
  */
-readonly class RawRecord implements \ArrayAccess, RecordInterface
+readonly class RawRecord implements RecordInterface
 {
     public function __construct(
         protected int $uid,
@@ -71,36 +72,30 @@ readonly class RawRecord implements \ArrayAccess, RecordInterface
         return $this->properties + ['uid' => $this->uid, 'pid' => $this->pid];
     }
 
-    /**
-     * In addition to `isset()`, this considers `null` values as well.
-     */
-    public function isDefined(int|string $offset): bool
+    public function has(string $id): bool
     {
-        return array_key_exists($offset, $this->properties);
+        return array_key_exists($id, $this->properties);
     }
 
-    public function offsetExists(mixed $offset): bool
+    public function get(string $id): mixed
     {
-        return isset($this->properties[$offset]);
-    }
-
-    public function offsetGet(mixed $offset): mixed
-    {
-        return $this->properties[$offset] ?? null;
-    }
+        if (!$this->has($id)) {
+            throw new RecordPropertyNotFoundException(
+                'Record property "' . $id . '" is not available.',
+                1725892140
+            );
+        }
 
-    public function offsetSet(mixed $offset, mixed $value): void
-    {
-        throw new \InvalidArgumentException('Record properties cannot be set.', 1712139284);
+        return $this->properties[$id] ?? null;
     }
 
-    public function offsetUnset(mixed $offset): void
+    public function getComputedProperties(): ComputedProperties
     {
-        throw new \InvalidArgumentException('Record properties cannot be unset.', 1712139283);
+        return $this->computedProperties;
     }
 
-    public function getComputedProperties(): ComputedProperties
+    public function getRawRecord(): RawRecord
     {
-        return $this->computedProperties;
+        return $this;
     }
 }
diff --git a/typo3/sysext/core/Classes/Domain/Record.php b/typo3/sysext/core/Classes/Domain/Record.php
index 05931dd47c2bb3d6ea0ca31669d34d006481dc58..c5f42222ccd893c81415b652fafa0efd1de2aca6 100644
--- a/typo3/sysext/core/Classes/Domain/Record.php
+++ b/typo3/sysext/core/Classes/Domain/Record.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Domain;
 
+use TYPO3\CMS\Core\Domain\Exception\RecordPropertyException;
+use TYPO3\CMS\Core\Domain\Exception\RecordPropertyNotFoundException;
 use TYPO3\CMS\Core\Domain\Record\ComputedProperties;
 use TYPO3\CMS\Core\Domain\Record\LanguageInfo;
 use TYPO3\CMS\Core\Domain\Record\SystemProperties;
@@ -27,12 +29,12 @@ use TYPO3\CMS\Core\Domain\Record\VersionInfo;
  *
  * @internal not part of public API, as this needs to be streamlined and proven
  */
-class Record implements \ArrayAccess, RecordInterface
+class Record implements RecordInterface
 {
     public function __construct(
         protected readonly RawRecord $rawRecord,
         protected array $properties,
-        protected readonly ?SystemProperties $systemProperties
+        protected readonly ?SystemProperties $systemProperties = null,
     ) {}
 
     public function getUid(): int
@@ -73,18 +75,18 @@ class Record implements \ArrayAccess, RecordInterface
         return ['uid' => $this->getUid(), 'pid' => $this->getPid()] + $this->properties;
     }
 
-    public function offsetExists(mixed $offset): bool
+    public function has(string $id): bool
     {
-        if (isset($this->properties[$offset])) {
+        if (array_key_exists($id, $this->properties)) {
             return true;
         }
 
-        if (in_array($offset, ['uid', 'pid'], true)) {
+        if (in_array($id, ['uid', 'pid'], true)) {
             // Enable access of uid and pid via array access
             return true;
         }
 
-        if ($this->getRecordType() === null && isset($this->rawRecord[$offset])) {
+        if ($this->getRecordType() === null && $this->rawRecord->has($id)) {
             // Only fall back to the raw record in case no record type is defined.
             // This allows to properly check for only record type specific fields.
             return true;
@@ -93,39 +95,38 @@ class Record implements \ArrayAccess, RecordInterface
         return false;
     }
 
-    public function offsetGet(mixed $offset): mixed
+    public function get(string $id): mixed
     {
-        if (isset($this->properties[$offset])) {
-            $property = $this->properties[$offset];
+        if (array_key_exists($id, $this->properties)) {
+            $property = $this->properties[$id];
             if ($property instanceof RecordPropertyClosure) {
-                $property = $property->instantiate();
-                $this->properties[$offset] = $property;
+                try {
+                    $property = $property->instantiate();
+                } catch (\Exception $e) {
+                    // Consumers of this method can rely on catching ContainerExceptionInterface
+                    throw new RecordPropertyException(
+                        'An exception occured while instantiating record property "' . $id . '"',
+                        1725892139,
+                        $e
+                    );
+                }
+                $this->properties[$id] = $property;
             }
             return $property;
         }
 
-        if (in_array($offset, ['uid', 'pid'], true)) {
+        if (in_array($id, ['uid', 'pid'], true)) {
             // Enable access of uid and pid via array access
-            return $this->rawRecord[$offset];
+            return $this->rawRecord->get($id);
         }
 
-        if ($this->getRecordType() === null && isset($this->rawRecord[$offset])) {
+        if ($this->getRecordType() === null && $this->rawRecord->has($id)) {
             // Only fall back to the raw record in case no record type is defined.
             // This ensures that only record type specific fields are being returned.
-            return $this->rawRecord[$offset];
+            return $this->rawRecord->get($id);
         }
 
-        return null;
-    }
-
-    public function offsetSet(mixed $offset, mixed $value): void
-    {
-        throw new \InvalidArgumentException('Record properties cannot be modified.', 1712139281);
-    }
-
-    public function offsetUnset(mixed $offset): void
-    {
-        throw new \InvalidArgumentException('Record properties cannot be unset.', 1712139282);
+        throw new RecordPropertyNotFoundException('Record property "' . $id . '" is not available.', 1725892138);
     }
 
     public function getVersionInfo(): ?VersionInfo
diff --git a/typo3/sysext/core/Classes/Domain/RecordFactory.php b/typo3/sysext/core/Classes/Domain/RecordFactory.php
index 60c3e8b65f2d9f06ac5245f6459c7d3597b638a5..76b5384f0bc0729ae8d678f590e059941eb66088 100644
--- a/typo3/sysext/core/Classes/Domain/RecordFactory.php
+++ b/typo3/sysext/core/Classes/Domain/RecordFactory.php
@@ -20,6 +20,8 @@ namespace TYPO3\CMS\Core\Domain;
 use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\DataHandling\RecordFieldTransformer;
+use TYPO3\CMS\Core\Domain\Exception\IncompleteRecordException;
+use TYPO3\CMS\Core\Domain\Exception\RecordPropertyNotFoundException;
 use TYPO3\CMS\Core\Domain\Record\ComputedProperties;
 use TYPO3\CMS\Core\Domain\Record\LanguageInfo;
 use TYPO3\CMS\Core\Domain\Record\SystemProperties;
@@ -64,7 +66,7 @@ readonly class RecordFactory
      * This method does not handle special expansion of fields.
      * @todo Now unused - we might want to remove this again
      */
-    public function createFromDatabaseRow(string $table, array $record): Record
+    public function createFromDatabaseRow(string $table, array $record): RecordInterface
     {
         $rawRecord = $this->createRawRecord($table, $record);
         $schema = $this->schemaFactory->get($table);
@@ -89,7 +91,7 @@ readonly class RecordFactory
      * their values resolved and extended. A typical use-case is resolving
      * of related records, or using \DateTimeImmutable objects for datetime fields.
      */
-    public function createResolvedRecordFromDatabaseRow(string $table, array $record, ?Context $context = null): Record
+    public function createResolvedRecordFromDatabaseRow(string $table, array $record, ?Context $context = null): RecordInterface
     {
         $context = $context ?? GeneralUtility::makeInstance(Context::class);
         $properties = [];
@@ -152,7 +154,7 @@ readonly class RecordFactory
     /**
      * Quick helper function in order to avoid duplicate code.
      */
-    protected function createRecord(RawRecord $rawRecord, array $properties): Record
+    protected function createRecord(RawRecord $rawRecord, array $properties): RecordInterface
     {
         $schema = $this->schemaFactory->get($rawRecord->getMainType());
         [$properties, $systemProperties] = $this->extractSystemInformation(
@@ -189,15 +191,22 @@ readonly class RecordFactory
             $languageCapability = $schema->getCapability(TcaSchemaCapability::Language);
             $languageField = $languageCapability->getLanguageField()->getName();
             $transOrigPointerField = $languageCapability->getTranslationOriginPointerField()->getName();
-            $translationSourceField = $languageCapability->hasTranslationSourceField() ? $languageCapability->getTranslationSourceField()->getName() : null;
-            $systemProperties['language'] = new LanguageInfo(
-                (int)$rawRecord[$languageField],
-                (int)$rawRecord[$transOrigPointerField],
-                $translationSourceField ? (int)$rawRecord[$translationSourceField] : null,
-            );
+            $translationSourceField = $languageCapability->hasTranslationSourceField() ? $languageCapability->getTranslationSourceField()->getName() : '';
+            try {
+                $systemProperties['language'] = new LanguageInfo(
+                    (int)$rawRecord->get($languageField),
+                    (int)$rawRecord->get($transOrigPointerField),
+                    $rawRecord->has($translationSourceField) ? (int)$rawRecord->get($translationSourceField) : null,
+                );
+            } catch (RecordPropertyNotFoundException $e) {
+                throw new IncompleteRecordException(
+                    'Table "' . $schema->getName() . '" is defined as language aware but the record misses necessary fields: ' . $e->getMessage(),
+                    1726046917
+                );
+            }
             unset($properties[$languageField]);
             unset($properties[$transOrigPointerField]);
-            if ($translationSourceField !== null) {
+            if ($translationSourceField !== '') {
                 unset($properties[$translationSourceField]);
             }
             if ($languageCapability->hasDiffSourceField()) {
@@ -208,12 +217,19 @@ readonly class RecordFactory
 
         // Workspaces.
         if ($schema->isWorkspaceAware()) {
-            $systemProperties['version'] = new VersionInfo(
-                (int)$rawRecord['t3ver_wsid'],
-                (int)$rawRecord['t3ver_oid'],
-                VersionState::tryFrom((int)$rawRecord['t3ver_state']),
-                (int)$rawRecord['t3ver_stage'],
-            );
+            try {
+                $systemProperties['version'] = new VersionInfo(
+                    (int)$rawRecord->get('t3ver_wsid'),
+                    (int)$rawRecord->get('t3ver_oid'),
+                    VersionState::tryFrom((int)$rawRecord->get('t3ver_state')),
+                    (int)$rawRecord->get('t3ver_stage'),
+                );
+            } catch (RecordPropertyNotFoundException $e) {
+                throw new IncompleteRecordException(
+                    'Table "' . $schema->getName() . '" is defined as workspace aware but the record misses necessary fields: ' . $e->getMessage(),
+                    1726046918
+                );
+            }
             unset(
                 $properties['t3ver_wsid'],
                 $properties['t3ver_oid'],
@@ -230,43 +246,45 @@ readonly class RecordFactory
             /** @var SystemInternalFieldCapability|FieldCapability $capabilityInstance */
             $capabilityInstance = $schema->getCapability($capability);
             $fieldName = $capabilityInstance->getFieldName();
-            // Field is not set in the original record, just skip it
-            if (!$rawRecord->isDefined($fieldName)) {
-                continue;
+            if (!$rawRecord->has($fieldName)) {
+                throw new IncompleteRecordException(
+                    'Table "' . $schema->getName() . '" has capability "' . $capability->name . '" set but the record misses the corresponding field "' . $fieldName . '"',
+                    1726046919
+                );
             }
             switch ($capability) {
                 case TcaSchemaCapability::CreatedAt:
-                    $systemProperties['createdAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord[$fieldName]);
+                    $systemProperties['createdAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord->get($fieldName));
                     break;
                 case TcaSchemaCapability::UpdatedAt:
-                    $systemProperties['lastUpdatedAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord[$fieldName]);
+                    $systemProperties['lastUpdatedAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord->get($fieldName));
                     break;
                 case TcaSchemaCapability::RestrictionStartTime:
-                    $systemProperties['publishAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord[$fieldName]);
+                    $systemProperties['publishAt'] = (new \DateTimeImmutable())->setTimestamp($rawRecord->get($fieldName));
                     break;
                 case TcaSchemaCapability::RestrictionEndTime:
-                    $systemProperties['publishUntil'] = (new \DateTimeImmutable())->setTimestamp($rawRecord[$fieldName]);
+                    $systemProperties['publishUntil'] = (new \DateTimeImmutable())->setTimestamp($rawRecord->get($fieldName));
                     break;
 
                 case TcaSchemaCapability::SoftDelete:
-                    $systemProperties['isDeleted'] = (bool)($rawRecord[$fieldName]);
+                    $systemProperties['isDeleted'] = (bool)($rawRecord->get($fieldName));
                     break;
                 case TcaSchemaCapability::EditLock:
-                    $systemProperties['isLockedForEditing'] = (bool)($rawRecord[$fieldName]);
+                    $systemProperties['isLockedForEditing'] = (bool)($rawRecord->get($fieldName));
                     break;
                 case TcaSchemaCapability::RestrictionDisabledField:
-                    $systemProperties['isDisabled'] = (bool)($rawRecord[$fieldName]);
+                    $systemProperties['isDisabled'] = (bool)($rawRecord->get($fieldName));
                     break;
                 case TcaSchemaCapability::InternalDescription:
-                    $systemProperties['description'] = $rawRecord[$fieldName];
+                    $systemProperties['description'] = $rawRecord->get($fieldName);
                     break;
                 case TcaSchemaCapability::SortByField:
-                    $systemProperties['sorting'] = (int)($rawRecord[$fieldName]);
+                    $systemProperties['sorting'] = (int)($rawRecord->get($fieldName));
                     break;
                 case TcaSchemaCapability::RestrictionUserGroup:
                     $systemProperties['userGroupRestriction'] = GeneralUtility::intExplode(
                         ',',
-                        $rawRecord[$fieldName],
+                        $rawRecord->get($fieldName),
                         true
                     );
                     break;
diff --git a/typo3/sysext/core/Classes/Domain/RecordInterface.php b/typo3/sysext/core/Classes/Domain/RecordInterface.php
index 6f8adb7409c7e14783f132dbc1735d9a21c68ce6..a7267a923d7cf068983bb352ba07a9d56e6df8f4 100644
--- a/typo3/sysext/core/Classes/Domain/RecordInterface.php
+++ b/typo3/sysext/core/Classes/Domain/RecordInterface.php
@@ -17,10 +17,13 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Domain;
 
+use Psr\Container\ContainerInterface;
+use TYPO3\CMS\Core\Domain\Record\ComputedProperties;
+
 /**
  * An interface for database / TCA records.
  */
-interface RecordInterface
+interface RecordInterface extends ContainerInterface
 {
     public function getUid(): int;
     public function getPid(): int;
@@ -43,4 +46,8 @@ interface RecordInterface
     public function getMainType(): string;
 
     public function toArray(): array;
+
+    public function getRawRecord(): ?RawRecord;
+
+    public function getComputedProperties(): ComputedProperties;
 }
diff --git a/typo3/sysext/core/Documentation/Changelog/13.2/Feature-103783-RecordTransformationDataProcessor.rst b/typo3/sysext/core/Documentation/Changelog/13.2/Feature-103783-RecordTransformationDataProcessor.rst
index 1597e548c4df21c1b08ebc812681b855eaa16749..34b95e086bcb718109a764014156309199d8a8aa 100644
--- a/typo3/sysext/core/Documentation/Changelog/13.2/Feature-103783-RecordTransformationDataProcessor.rst
+++ b/typo3/sysext/core/Documentation/Changelog/13.2/Feature-103783-RecordTransformationDataProcessor.rst
@@ -89,9 +89,9 @@ is most of all a better organized overview of all available information. E.g.
 the property `properties` lists all relevant fields for the current Content
 Type.
 
-We are dealing with an object here, which behaves like an array. In short: you
-can access your record properties as you are used to with :html:`{record.title}`
-or :html:`{record.uid}`. In addition, you gain special, context-aware properties
+We are dealing with an object here. You however can access your record
+properties as you are used to with :html:`{record.title}` or
+:html:`{record.uid}`. In addition, you gain special, context-aware properties
 like the language :html:`{record.languageId}` or workspace
 :html:`{data.versionInfo.workspaceId}`.
 
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/RecordFieldTransformerTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/RecordFieldTransformerTest.php
index 75f11ff40db7f1168369f120f9c7cf272a1ad7ad..f2735f5f740730fee223d2400ff91feaed048b8a 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/RecordFieldTransformerTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/RecordFieldTransformerTest.php
@@ -24,6 +24,7 @@ use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\LanguageAspect;
 use TYPO3\CMS\Core\Context\WorkspaceAspect;
 use TYPO3\CMS\Core\DataHandling\RecordFieldTransformer;
+use TYPO3\CMS\Core\Domain\RawRecord;
 use TYPO3\CMS\Core\Domain\Record;
 use TYPO3\CMS\Core\Domain\RecordFactory;
 use TYPO3\CMS\Core\Domain\RecordPropertyClosure;
@@ -58,7 +59,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $propertyClosure = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -70,8 +71,8 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertIsArray($result->getProperties());
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertInstanceOf(FileReference::class, $resolvedRecord['image']);
-        self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord['image']->getIdentifier());
+        self::assertInstanceOf(FileReference::class, $resolvedRecord->get('image'));
+        self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord->get('image')->getIdentifier());
     }
 
     #[Test]
@@ -83,7 +84,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $propertyClosure = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -92,7 +93,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertNull($result);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertNull($resolvedRecord['image']);
+        self::assertNull($resolvedRecord->get('image'));
     }
 
     #[Test]
@@ -104,7 +105,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -117,9 +118,9 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertInstanceOf(LazyFileReferenceCollection::class, $result);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertInstanceOf(LazyFileReferenceCollection::class, $resolvedRecord['media']);
-        self::assertInstanceOf(FileReference::class, $resolvedRecord['media'][0]);
-        self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord['media'][0]->getIdentifier());
+        self::assertInstanceOf(LazyFileReferenceCollection::class, $resolvedRecord->get('media'));
+        self::assertInstanceOf(FileReference::class, $resolvedRecord->get('media')[0]);
+        self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord->get('media')[0]->getIdentifier());
     }
 
     #[Test]
@@ -131,7 +132,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -144,10 +145,10 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertInstanceOf(LazyFileReferenceCollection::class, $result);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertCount(1, $resolvedRecord['assets']);
-        self::assertInstanceOf(LazyFileReferenceCollection::class, $resolvedRecord['assets']);
-        self::assertInstanceOf(FileReference::class, $resolvedRecord['assets'][0]);
-        self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord['assets'][0]->getIdentifier());
+        self::assertCount(1, $resolvedRecord->get('assets'));
+        self::assertInstanceOf(LazyFileReferenceCollection::class, $resolvedRecord->get('assets'));
+        self::assertInstanceOf(FileReference::class, $resolvedRecord->get('assets')[0]);
+        self::assertEquals('/kasper-skarhoj1.jpg', $resolvedRecord->get('assets')[0]->getIdentifier());
     }
 
     #[Test]
@@ -159,7 +160,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $propertyClosure = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -171,10 +172,10 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertCount(1, $result->getFiles());
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertInstanceOf(Folder::class, $resolvedRecord['typo3tests_contentelementb_folder']);
-        self::assertEquals('/', $resolvedRecord['typo3tests_contentelementb_folder']->getIdentifier());
-        self::assertEquals('1:/', $resolvedRecord['typo3tests_contentelementb_folder']->getCombinedIdentifier());
-        self::assertCount(1, $resolvedRecord['typo3tests_contentelementb_folder']->getFiles());
+        self::assertInstanceOf(Folder::class, $resolvedRecord->get('typo3tests_contentelementb_folder'));
+        self::assertEquals('/', $resolvedRecord->get('typo3tests_contentelementb_folder')->getIdentifier());
+        self::assertEquals('1:/', $resolvedRecord->get('typo3tests_contentelementb_folder')->getCombinedIdentifier());
+        self::assertCount(1, $resolvedRecord->get('typo3tests_contentelementb_folder')->getFiles());
     }
 
     #[Test]
@@ -186,7 +187,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $propertyClosure = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -195,7 +196,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertNull($result);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertNull($resolvedRecord['typo3tests_contentelementb_folder']);
+        self::assertNull($resolvedRecord->get('typo3tests_contentelementb_folder'));
     }
 
     #[Test]
@@ -207,7 +208,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class),
         );
 
@@ -225,12 +226,12 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertCount(1, $result[1]->getFiles());
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertInstanceOf(LazyFolderCollection::class, $resolvedRecord['typo3tests_contentelementb_folder_recursive']);
-        self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_folder_recursive']);
-        self::assertInstanceOf(Folder::class, $resolvedRecord['typo3tests_contentelementb_folder_recursive'][0]);
-        self::assertEquals('/sub/', $resolvedRecord['typo3tests_contentelementb_folder_recursive'][1]->getIdentifier());
-        self::assertEquals('1:/sub/', $resolvedRecord['typo3tests_contentelementb_folder_recursive'][1]->getCombinedIdentifier());
-        self::assertCount(1, $resolvedRecord['typo3tests_contentelementb_folder_recursive'][1]->getFiles());
+        self::assertInstanceOf(LazyFolderCollection::class, $resolvedRecord->get('typo3tests_contentelementb_folder_recursive'));
+        self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_folder_recursive'));
+        self::assertInstanceOf(Folder::class, $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')[0]);
+        self::assertEquals('/sub/', $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')[1]->getIdentifier());
+        self::assertEquals('1:/sub/', $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')[1]->getCombinedIdentifier());
+        self::assertCount(1, $resolvedRecord->get('typo3tests_contentelementb_folder_recursive')[1]->getFiles());
     }
 
     #[Test]
@@ -242,20 +243,20 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
-        self::assertSame('lorem foo bar', $result[0]['fieldA']);
-        self::assertSame('lorem foo bar 2', $result[1]['fieldA']);
+        self::assertSame('lorem foo bar', $result[0]->get('fieldA'));
+        self::assertSame('lorem foo bar 2', $result[1]->get('fieldA'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_collection']);
-        self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_collection']);
-        self::assertSame('lorem foo bar', $resolvedRecord['typo3tests_contentelementb_collection'][0]['fieldA']);
-        self::assertSame('lorem foo bar 2', $resolvedRecord['typo3tests_contentelementb_collection'][1]['fieldA']);
+        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_collection'));
+        self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_collection'));
+        self::assertSame('lorem foo bar', $resolvedRecord->get('typo3tests_contentelementb_collection')[0]->get('fieldA'));
+        self::assertSame('lorem foo bar 2', $resolvedRecord->get('typo3tests_contentelementb_collection')[1]->get('fieldA'));
     }
 
     #[Test]
@@ -267,26 +268,26 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
-        self::assertSame('lorem foo bar A', $result[0]['fieldA']);
-        self::assertSame('lorem foo bar A2', $result[1]['fieldA']);
-        self::assertCount(2, $result[0]['collection_inner']);
-        self::assertSame('lorem foo bar B', $result[0]['collection_inner'][0]['fieldB']);
-        self::assertSame('lorem foo bar B2', $result[0]['collection_inner'][1]['fieldB']);
+        self::assertSame('lorem foo bar A', $result[0]->get('fieldA'));
+        self::assertSame('lorem foo bar A2', $result[1]->get('fieldA'));
+        self::assertCount(2, $result[0]->get('collection_inner'));
+        self::assertSame('lorem foo bar B', $result[0]->get('collection_inner')[0]->get('fieldB'));
+        self::assertSame('lorem foo bar B2', $result[0]->get('collection_inner')[1]->get('fieldB'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_collection_recursive']);
-        self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_collection_recursive']);
-        self::assertSame('lorem foo bar A', $resolvedRecord['typo3tests_contentelementb_collection_recursive'][0]['fieldA']);
-        self::assertSame('lorem foo bar A2', $resolvedRecord['typo3tests_contentelementb_collection_recursive'][1]['fieldA']);
-        self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_collection_recursive'][0]['collection_inner']);
-        self::assertSame('lorem foo bar B', $resolvedRecord['typo3tests_contentelementb_collection_recursive'][0]['collection_inner'][0]['fieldB']);
-        self::assertSame('lorem foo bar B2', $resolvedRecord['typo3tests_contentelementb_collection_recursive'][0]['collection_inner'][1]['fieldB']);
+        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_collection_recursive'));
+        self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_collection_recursive'));
+        self::assertSame('lorem foo bar A', $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[0]->get('fieldA'));
+        self::assertSame('lorem foo bar A2', $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[1]->get('fieldA'));
+        self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[0]->get('collection_inner'));
+        self::assertSame('lorem foo bar B', $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[0]->get('collection_inner')[0]->get('fieldB'));
+        self::assertSame('lorem foo bar B2', $resolvedRecord->get('typo3tests_contentelementb_collection_recursive')[0]->get('collection_inner')[1]->get('fieldB'));
     }
 
     #[Test]
@@ -306,20 +307,20 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
-        self::assertSame('lorem foo bar WS', $result[0]['fieldA']);
-        self::assertSame('lorem foo bar 2 WS', $result[1]['fieldA']);
+        self::assertSame('lorem foo bar WS', $result[0]->get('fieldA'));
+        self::assertSame('lorem foo bar 2 WS', $result[1]->get('fieldA'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_collection']);
-        self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_collection']);
-        self::assertSame('lorem foo bar WS', $resolvedRecord['typo3tests_contentelementb_collection'][0]['fieldA']);
-        self::assertSame('lorem foo bar 2 WS', $resolvedRecord['typo3tests_contentelementb_collection'][1]['fieldA']);
+        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_collection'));
+        self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_collection'));
+        self::assertSame('lorem foo bar WS', $resolvedRecord->get('typo3tests_contentelementb_collection')[0]->get('fieldA'));
+        self::assertSame('lorem foo bar 2 WS', $resolvedRecord->get('typo3tests_contentelementb_collection')[1]->get('fieldA'));
     }
 
     #[Test]
@@ -331,19 +332,19 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
-        self::assertSame('Category 1', $result[0]['title']);
-        self::assertSame('Category 2', $result[1]['title']);
+        self::assertSame('Category 1', $result[0]->get('title'));
+        self::assertSame('Category 2', $result[1]->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_categories_mm']);
-        self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_categories_mm']);
-        self::assertSame('Category 1', $resolvedRecord['typo3tests_contentelementb_categories_mm'][0]['title']);
-        self::assertSame('Category 2', $resolvedRecord['typo3tests_contentelementb_categories_mm'][1]['title']);
+        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_categories_mm'));
+        self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_categories_mm'));
+        self::assertSame('Category 1', $resolvedRecord->get('typo3tests_contentelementb_categories_mm')[0]->get('title'));
+        self::assertSame('Category 2', $resolvedRecord->get('typo3tests_contentelementb_categories_mm')[1]->get('title'));
     }
 
     #[Test]
@@ -365,14 +366,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
         // @todo: this should be the other way around, but currently RelationResolver cannot handle different sorting in WS
-        self::assertSame('Category 2 ws', $result[1]['title']);
-        self::assertSame('Category 1 ws', $result[0]['title']);
+        self::assertSame('Category 2 ws', $result[1]->get('title'));
+        self::assertSame('Category 1 ws', $result[0]->get('title'));
     }
 
     #[Test]
@@ -392,17 +393,17 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $context
         );
 
         self::assertCount(1, $result);
-        self::assertSame('Category 1 translated', $result[0]['title']);
+        self::assertSame('Category 1 translated', $result[0]->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', array_replace($dummyRecord->toArray(), ['uid' => 381]), $context);
-        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_categories_mm']);
-        self::assertCount(1, $resolvedRecord['typo3tests_contentelementb_categories_mm']);
-        self::assertSame('Category 1 translated', $resolvedRecord['typo3tests_contentelementb_categories_mm'][0]['title']);
+        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_categories_mm'));
+        self::assertCount(1, $resolvedRecord->get('typo3tests_contentelementb_categories_mm'));
+        self::assertSame('Category 1 translated', $resolvedRecord->get('typo3tests_contentelementb_categories_mm')[0]->get('title'));
     }
 
     #[Test]
@@ -422,17 +423,17 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $context
         );
 
         self::assertCount(1, $result);
-        self::assertSame('Category 1 translated', $result[0]['title']);
+        self::assertSame('Category 1 translated', $result[0]->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', array_replace($dummyRecord->toArray(), ['uid' => 381]), $context);
-        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_categories_mm']);
-        self::assertCount(1, $resolvedRecord['typo3tests_contentelementb_categories_mm']);
-        self::assertSame('Category 1 translated', $resolvedRecord['typo3tests_contentelementb_categories_mm'][0]['title']);
+        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_categories_mm'));
+        self::assertCount(1, $resolvedRecord->get('typo3tests_contentelementb_categories_mm'));
+        self::assertSame('Category 1 translated', $resolvedRecord->get('typo3tests_contentelementb_categories_mm')[0]->get('title'));
     }
 
     #[Test]
@@ -446,7 +447,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $propertyClosure = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -454,12 +455,12 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $result = $propertyClosure->instantiate();
         self::assertInstanceOf(Record::class, $result);
         self::assertSame(2, $result->getUid());
-        self::assertSame('Category 1', $result['title']);
+        self::assertSame('Category 1', $result->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertInstanceOf(Record::class, $resolvedRecord['typo3tests_contentelementb_categories_11']);
-        self::assertSame(2, $resolvedRecord['typo3tests_contentelementb_categories_11']['uid']);
-        self::assertSame('Category 1', $resolvedRecord['typo3tests_contentelementb_categories_11']['title']);
+        self::assertInstanceOf(Record::class, $resolvedRecord->get('typo3tests_contentelementb_categories_11'));
+        self::assertSame(2, $resolvedRecord->get('typo3tests_contentelementb_categories_11')->getUid());
+        self::assertSame('Category 1', $resolvedRecord->get('typo3tests_contentelementb_categories_11')->get('title'));
     }
 
     #[Test]
@@ -473,20 +474,20 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
-        self::assertSame('Category 1', $result[0]['title']);
-        self::assertSame('Category 2', $result[1]['title']);
+        self::assertSame('Category 1', $result[0]->get('title'));
+        self::assertSame('Category 2', $result[1]->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertCount(2, $resolvedRecord['typo3tests_contentelementb_categories_1m']);
-        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord['typo3tests_contentelementb_categories_1m']);
-        self::assertSame('Category 1', $resolvedRecord['typo3tests_contentelementb_categories_1m'][0]['title']);
-        self::assertSame('Category 2', $resolvedRecord['typo3tests_contentelementb_categories_1m'][1]['title']);
+        self::assertCount(2, $resolvedRecord->get('typo3tests_contentelementb_categories_1m'));
+        self::assertInstanceOf(LazyRecordCollection::class, $resolvedRecord->get('typo3tests_contentelementb_categories_1m'));
+        self::assertSame('Category 1', $resolvedRecord->get('typo3tests_contentelementb_categories_1m')[0]->get('title'));
+        self::assertSame('Category 2', $resolvedRecord->get('typo3tests_contentelementb_categories_1m')[1]->get('title'));
     }
 
     #[Test]
@@ -500,7 +501,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $propertyClosure = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -508,15 +509,15 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $result = $propertyClosure->instantiate();
         self::assertInstanceOf(Record::class, $result);
         self::assertSame(1906, $result->getUid());
-        self::assertSame(1906, $result['uid']);
-        self::assertSame('Page 1', $result['title']);
+        self::assertSame(1906, $result->get('uid'));
+        self::assertSame('Page 1', $result->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_relation'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_relation');
         self::assertInstanceOf(Record::class, $resolvedRelation);
         self::assertSame(1906, $resolvedRelation->getUid());
-        self::assertSame(1906, $resolvedRelation['uid']);
-        self::assertSame('Page 1', $resolvedRelation['title']);
+        self::assertSame(1906, $resolvedRelation->get('uid'));
+        self::assertSame('Page 1', $resolvedRelation->get('title'));
     }
 
     #[Test]
@@ -530,23 +531,23 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
-        self::assertSame('Page 1', $result[0]['title']);
-        self::assertSame('Page 2', $result[1]['title']);
+        self::assertSame('Page 1', $result[0]->get('title'));
+        self::assertSame('Page 2', $result[1]->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_relations'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_relations');
         self::assertCount(2, $resolvedRelation);
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
         self::assertSame(1906, $resolvedRelation[0]->getUid());
-        self::assertSame(1906, $resolvedRelation[0]['uid']);
-        self::assertSame('Page 1', $resolvedRelation[0]['title']);
-        self::assertSame('Page 2', $resolvedRelation[1]['title']);
+        self::assertSame(1906, $resolvedRelation[0]->get('uid'));
+        self::assertSame('Page 1', $resolvedRelation[0]->get('title'));
+        self::assertSame('Page 2', $resolvedRelation[1]->get('title'));
     }
 
     #[Test]
@@ -560,7 +561,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -569,11 +570,11 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertSame(260, $result[0]->getUid());
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_circular_relation'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_circular_relation');
         self::assertCount(1, $resolvedRelation);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
         self::assertSame(260, $resolvedRelation[0]->getUid());
-        self::assertSame(260, $resolvedRelation[0]['uid']);
+        self::assertSame(260, $resolvedRelation[0]->get('uid'));
     }
 
     #[Test]
@@ -587,29 +588,29 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertInstanceOf(LazyRecordCollection::class, $result);
         self::assertCount(2, $result);
-        self::assertSame('Record 1', $result[0]['title']);
-        self::assertSame('Record 2', $result[1]['title']);
-        self::assertCount(1, $result[0]['record_collection']);
-        self::assertCount(1, $result[1]['record_collection']);
-        self::assertSame('Collection 1', $result[0]['record_collection'][0]['text']);
-        self::assertSame('Collection 2', $result[1]['record_collection'][0]['text']);
+        self::assertSame('Record 1', $result[0]->get('title'));
+        self::assertSame('Record 2', $result[1]->get('title'));
+        self::assertCount(1, $result[0]->get('record_collection'));
+        self::assertCount(1, $result[1]->get('record_collection'));
+        self::assertSame('Collection 1', $result[0]->get('record_collection')[0]->get('text'));
+        self::assertSame('Collection 2', $result[1]->get('record_collection')[0]->get('text'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_record_relation_recursive'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_record_relation_recursive');
         self::assertCount(2, $resolvedRelation);
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
-        self::assertSame('Record 1', $resolvedRelation[0]['title']);
-        self::assertSame('Record 2', $resolvedRelation[1]['title']);
-        self::assertCount(1, $resolvedRelation[0]['record_collection']);
-        self::assertCount(1, $resolvedRelation[1]['record_collection']);
-        self::assertSame('Collection 1', $resolvedRelation[0]['record_collection'][0]['text']);
-        self::assertSame('Collection 2', $resolvedRelation[1]['record_collection'][0]['text']);
+        self::assertSame('Record 1', $resolvedRelation[0]->get('title'));
+        self::assertSame('Record 2', $resolvedRelation[1]->get('title'));
+        self::assertCount(1, $resolvedRelation[0]->get('record_collection'));
+        self::assertCount(1, $resolvedRelation[1]->get('record_collection'));
+        self::assertSame('Collection 1', $resolvedRelation[0]->get('record_collection')[0]->get('text'));
+        self::assertSame('Collection 2', $resolvedRelation[1]->get('record_collection')[0]->get('text'));
     }
 
     #[Test]
@@ -630,21 +631,21 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
-        self::assertSame('Page 1 ws', $result[0]['title']);
-        self::assertSame('Page 2 ws', $result[1]['title']);
+        self::assertSame('Page 1 ws', $result[0]->get('title'));
+        self::assertSame('Page 2 ws', $result[1]->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_relations'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_relations');
         self::assertCount(2, $resolvedRelation);
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
-        self::assertSame('Page 1 ws', $resolvedRelation[0]['title']);
-        self::assertSame('Page 2 ws', $resolvedRelation[1]['title']);
+        self::assertSame('Page 1 ws', $resolvedRelation[0]->get('title'));
+        self::assertSame('Page 2 ws', $resolvedRelation[1]->get('title'));
     }
 
     #[Test]
@@ -658,24 +659,24 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
         self::assertCount(4, $result);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
-        self::assertSame('Page 1', $result[0]['title']);
-        self::assertSame('Page 2', $result[1]['title']);
-        self::assertSame('Content 1', $result[2]['header']);
-        self::assertSame('Content 2', $result[3]['header']);
+        self::assertSame('Page 1', $result[0]->get('title'));
+        self::assertSame('Page 2', $result[1]->get('title'));
+        self::assertSame('Content 1', $result[2]->get('header'));
+        self::assertSame('Content 2', $result[3]->get('header'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_content_relation'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_content_relation');
         self::assertCount(4, $resolvedRelation);
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
-        self::assertSame('Page 1', $resolvedRelation[0]['title']);
-        self::assertSame('Page 2', $resolvedRelation[1]['title']);
-        self::assertSame('Content 1', $resolvedRelation[2]['header']);
-        self::assertSame('Content 2', $resolvedRelation[3]['header']);
+        self::assertSame('Page 1', $resolvedRelation[0]->get('title'));
+        self::assertSame('Page 2', $resolvedRelation[1]->get('title'));
+        self::assertSame('Content 1', $resolvedRelation[2]->get('header'));
+        self::assertSame('Content 2', $resolvedRelation[3]->get('header'));
     }
 
     #[Test]
@@ -690,21 +691,21 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
-        self::assertSame('Page 1', $result[0]['title']);
-        self::assertSame('Page 2', $result[1]['title']);
+        self::assertSame('Page 1', $result[0]->get('title'));
+        self::assertSame('Page 2', $result[1]->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_pages_mm'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_pages_mm');
         self::assertCount(2, $resolvedRelation);
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
-        self::assertSame('Page 1', $resolvedRelation[0]['title']);
-        self::assertSame('Page 2', $resolvedRelation[1]['title']);
+        self::assertSame('Page 1', $resolvedRelation[0]->get('title'));
+        self::assertSame('Page 2', $resolvedRelation[1]->get('title'));
     }
 
     public static function multipleItemsAsArrayConversionDataProvider(): \Generator
@@ -752,14 +753,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertSame($expected, $result);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertSame($expected, $resolvedRecord[$fieldName]);
+        self::assertSame($expected, $resolvedRecord->get($fieldName));
     }
 
     public static function canConvertDateTimeDataProvider(): \Generator
@@ -802,14 +803,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertSame($expected, $result?->format('c'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertSame($expected, $resolvedRecord[$fieldName]?->format('c'));
+        self::assertSame($expected, $resolvedRecord->get($fieldName)?->format('c'));
     }
 
     #[Test]
@@ -822,14 +823,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertSame('1', $result);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertSame('1', $resolvedRecord['typo3tests_contentelementb_select_single']);
+        self::assertSame('1', $resolvedRecord->get('typo3tests_contentelementb_select_single'));
     }
 
     #[Test]
@@ -843,19 +844,19 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $propertyClosure = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertInstanceOf(RecordPropertyClosure::class, $propertyClosure);
         $result = $propertyClosure->instantiate();
         self::assertInstanceOf(Record::class, $result);
-        self::assertSame('Record 1', $result['title']);
+        self::assertSame('Record 1', $result->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_one_to_one'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_one_to_one');
         self::assertInstanceOf(Record::class, $resolvedRelation);
-        self::assertSame('Record 1', $resolvedRelation['title']);
+        self::assertSame('Record 1', $resolvedRelation->get('title'));
     }
 
     /**
@@ -872,19 +873,19 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $propertyClosure = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertInstanceOf(RecordPropertyClosure::class, $propertyClosure);
         $result = $propertyClosure->instantiate();
         self::assertInstanceOf(Record::class, $result);
-        self::assertSame('Record 1', $result['title']);
+        self::assertSame('Record 1', $result->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedField = $resolvedRecord['typo3tests_contentelementb_select_foreign_native'];
+        $resolvedField = $resolvedRecord->get('typo3tests_contentelementb_select_foreign_native');
         self::assertInstanceOf(Record::class, $resolvedField);
-        self::assertSame('Record 1', $resolvedField['title']);
+        self::assertSame('Record 1', $resolvedField->get('title'));
     }
 
     /**
@@ -901,7 +902,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $propertyClosure = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -910,7 +911,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertNull($result);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        self::assertNull($resolvedRecord['typo3tests_contentelementb_select_foreign_native']);
+        self::assertNull($resolvedRecord->get('typo3tests_contentelementb_select_foreign_native'));
     }
 
     /**
@@ -927,7 +928,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -935,7 +936,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertCount(0, $result);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign');
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
         self::assertCount(0, $resolvedRelation);
     }
@@ -954,7 +955,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -962,7 +963,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertCount(0, $result);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign_multiple'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign_multiple');
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
         self::assertCount(0, $resolvedRelation);
     }
@@ -978,20 +979,20 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
-        self::assertSame('Record 1', $result[0]['title']);
-        self::assertSame('Record 2', $result[1]['title']);
+        self::assertSame('Record 1', $result[0]->get('title'));
+        self::assertSame('Record 2', $result[1]->get('title'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign_multiple'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign_multiple');
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
         self::assertCount(2, $resolvedRelation);
-        self::assertSame('Record 1', $resolvedRelation[0]['title']);
-        self::assertSame('Record 2', $resolvedRelation[1]['title']);
+        self::assertSame('Record 1', $resolvedRelation[0]->get('title'));
+        self::assertSame('Record 2', $resolvedRelation[1]->get('title'));
     }
 
     #[Test]
@@ -1005,25 +1006,25 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(2, $result);
-        self::assertSame('Record 1', $result[0]['title']);
-        self::assertSame('Collection 1', $result[0]['record_collection'][0]['text']);
-        self::assertSame('Record 1', $result[1]['title']);
-        self::assertSame('Collection 1', $result[1]['record_collection'][0]['text']);
+        self::assertSame('Record 1', $result[0]->get('title'));
+        self::assertSame('Collection 1', $result[0]->get('record_collection')[0]->get('text'));
+        self::assertSame('Record 1', $result[1]->get('title'));
+        self::assertSame('Collection 1', $result[1]->get('record_collection')[0]->get('text'));
         self::assertSame($result[0], $result[1]);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign_multiple'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign_multiple');
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
         self::assertCount(2, $resolvedRelation);
-        self::assertSame('Record 1', $resolvedRelation[0]['title']);
-        self::assertSame('Collection 1', $resolvedRelation[0]['record_collection'][0]['text']);
-        self::assertSame('Record 1', $resolvedRelation[1]['title']);
-        self::assertSame('Collection 1', $resolvedRelation[1]['record_collection'][0]['text']);
+        self::assertSame('Record 1', $resolvedRelation[0]->get('title'));
+        self::assertSame('Collection 1', $resolvedRelation[0]->get('record_collection')[0]->get('text'));
+        self::assertSame('Record 1', $resolvedRelation[1]->get('title'));
+        self::assertSame('Collection 1', $resolvedRelation[1]->get('record_collection')[0]->get('text'));
         self::assertSame($resolvedRelation[0], $resolvedRelation[1]);
     }
 
@@ -1038,24 +1039,24 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
         self::assertCount(1, $result);
         self::assertInstanceOf(LazyRecordCollection::class, $result);
         $result = $result[0];
-        self::assertSame('Record 1', $result['title']);
-        self::assertCount(1, $result['record_collection']);
-        self::assertSame('Collection 1', $result['record_collection'][0]['text']);
+        self::assertSame('Record 1', $result->get('title'));
+        self::assertCount(1, $result->get('record_collection'));
+        self::assertSame('Collection 1', $result->get('record_collection')[0]->get('text'));
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_select_foreign'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_select_foreign');
         self::assertInstanceOf(LazyRecordCollection::class, $resolvedRelation);
         self::assertCount(1, $resolvedRelation);
-        self::assertSame('Record 1', $resolvedRelation[0]['title']);
-        self::assertCount(1, $resolvedRelation[0]['record_collection']);
-        self::assertSame('Collection 1', $resolvedRelation[0]['record_collection'][0]['text']);
+        self::assertSame('Record 1', $resolvedRelation[0]->get('title'));
+        self::assertCount(1, $resolvedRelation[0]->get('record_collection'));
+        self::assertSame('Collection 1', $resolvedRelation[0]->get('record_collection')[0]->get('text'));
     }
 
     #[Test]
@@ -1083,7 +1084,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -1092,7 +1093,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertSame('Text in Flex', $result['textarea']);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_flexfield'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_flexfield');
         self::assertIsArray($resolvedRelation);
         self::assertSame('Header in Flex', $resolvedRelation['header']);
         self::assertSame('Text in Flex', $resolvedRelation['textarea']);
@@ -1133,7 +1134,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         $subject = $this->get(RecordFieldTransformer::class);
         $result = $subject->transformField(
             $fieldInformation,
-            $dummyRecord->getRawRecord(),
+            $dummyRecord,
             $this->get(Context::class)
         );
 
@@ -1144,7 +1145,7 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         self::assertSame('12', $result['number']);
 
         $resolvedRecord = $this->get(RecordFactory::class)->createResolvedRecordFromDatabaseRow('tt_content', $dummyRecord->toArray());
-        $resolvedRelation = $resolvedRecord['typo3tests_contentelementb_flexfield'];
+        $resolvedRelation = $resolvedRecord->get('typo3tests_contentelementb_flexfield');
         self::assertIsArray($resolvedRelation);
         self::assertSame('Header in Flex', $resolvedRelation['header']);
         self::assertSame('Text in Flex', $resolvedRelation['textarea']);
@@ -1165,6 +1166,14 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
             'pid' => 1,
             'sys_language_uid' => 0,
             'l18n_parent' => 0,
+            't3ver_wsid' => 0,
+            't3ver_oid' => 0,
+            't3ver_state' => 0,
+            't3ver_stage' => 0,
+            'crdate' => 0,
+            'tstamp' => 0,
+            'deleted' => 0,
+            'sorting' => 0,
             'hidden' => 0,
             'starttime' => 0,
             'endtime' => 0,
@@ -1201,10 +1210,12 @@ final class RecordFieldTransformerTest extends FunctionalTestCase
         ];
     }
 
-    protected function createTestRecordObject(array $overriddenValues = []): Record
+    protected function createTestRecordObject(array $overriddenValues = []): RawRecord
     {
         $dummyRecordData = $this->getTestRecord();
         $dummyRecordData = array_replace($dummyRecordData, $overriddenValues);
-        return $this->get(RecordFactory::class)->createFromDatabaseRow('tt_content', $dummyRecordData);
+        return $this->get(RecordFactory::class)
+            ->createFromDatabaseRow('tt_content', $dummyRecordData)
+            ->getRawRecord();
     }
 }
diff --git a/typo3/sysext/core/Tests/Functional/Domain/RecordFactoryTest.php b/typo3/sysext/core/Tests/Functional/Domain/RecordFactoryTest.php
index c2ccd11ccde857e9b09c6052b55f251877d1492f..20ba0106c027f286554cc978f16a670d903a3126 100644
--- a/typo3/sysext/core/Tests/Functional/Domain/RecordFactoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/Domain/RecordFactoryTest.php
@@ -21,6 +21,8 @@ use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\LanguageAspect;
+use TYPO3\CMS\Core\Domain\Exception\IncompleteRecordException;
+use TYPO3\CMS\Core\Domain\Record;
 use TYPO3\CMS\Core\Domain\RecordFactory;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -41,8 +43,10 @@ final class RecordFactoryTest extends FunctionalTestCase
         $dbRow = BackendUtility::getRecord('pages', 1);
         $subject = $this->get(RecordFactory::class);
         $result = $subject->createFromDatabaseRow('pages', $dbRow);
-        self::assertSame(1, $result['uid']);
-        self::assertSame(0, $result['pid']);
+        self::assertSame(1, $result->getUid());
+        self::assertSame(1, $result->get('uid'));
+        self::assertSame(0, $result->getPid());
+        self::assertSame(0, $result->get('pid'));
     }
 
     #[Test]
@@ -50,6 +54,7 @@ final class RecordFactoryTest extends FunctionalTestCase
     {
         $dbRow = BackendUtility::getRecord('pages', 1);
         $subject = $this->get(RecordFactory::class);
+        /** @var Record $result */
         $result = $subject->createFromDatabaseRow('pages', $dbRow);
         self::assertSame($dbRow, $result->getRawRecord()->toArray());
         self::assertArrayNotHasKey('mount_pid', $result->toArray());
@@ -68,6 +73,7 @@ final class RecordFactoryTest extends FunctionalTestCase
     {
         $dbRow = BackendUtility::getRecord('tt_content', 1);
         $subject = $this->get(RecordFactory::class);
+        /** @var Record $result */
         $result = $subject->createFromDatabaseRow('tt_content', $dbRow);
         self::assertSame($dbRow, $result->getRawRecord()->toArray());
         self::assertArrayNotHasKey('pi_flexform', $result->toArray());
@@ -82,11 +88,12 @@ final class RecordFactoryTest extends FunctionalTestCase
     {
         $dbRow = BackendUtility::getRecord('be_groups', 9);
         $subject = $this->get(RecordFactory::class);
+        /** @var Record $result */
         $result = $subject->createFromDatabaseRow('be_groups', $dbRow);
         self::assertNull($result->getRecordType());
         self::assertSame('be_groups', $result->getFullType());
         self::assertSame($dbRow, $result->getRawRecord()->toArray());
-        self::assertSame('readFolder,writeFolder,addFolder,renameFolder,moveFolder,deleteFolder,readFile,writeFile,addFile,renameFile,replaceFile,moveFile,copyFile,deleteFile', $result['file_permissions']);
+        self::assertSame('readFolder,writeFolder,addFolder,renameFolder,moveFolder,deleteFolder,readFile,writeFile,addFile,renameFile,replaceFile,moveFile,copyFile,deleteFile', $result->get('file_permissions'));
     }
 
     #[Test]
@@ -97,6 +104,7 @@ final class RecordFactoryTest extends FunctionalTestCase
         $pageRepository = GeneralUtility::makeInstance(PageRepository::class, $context);
         $dbRow = $pageRepository->getPage(3);
         $subject = $this->get(RecordFactory::class);
+        /** @var Record $result */
         $result = $subject->createFromDatabaseRow('pages', $dbRow);
         self::assertSame(903, $result->getOverlaidUid());
         self::assertSame(903, $result->getComputedProperties()->getLocalizedUid());
@@ -113,6 +121,7 @@ final class RecordFactoryTest extends FunctionalTestCase
         $pageRepository = GeneralUtility::makeInstance(PageRepository::class, $context);
         $dbRow = $pageRepository->getPage(3);
         $subject = $this->get(RecordFactory::class);
+        /** @var Record $result */
         $result = $subject->createFromDatabaseRow('pages', $dbRow);
         self::assertSame(0, $result->getVersionInfo()->getWorkspaceId());
         self::assertSame(3, $result->getLanguageInfo()->getTranslationParent());
@@ -123,4 +132,40 @@ final class RecordFactoryTest extends FunctionalTestCase
         self::assertSame(1, $result->getComputedProperties()->getRequestedOverlayLanguageId());
         self::assertNull($result->getComputedProperties()->getVersionedUid());
     }
+
+    #[Test]
+    public function throwsIncompleteRecordExceptionForMissingLangauegField(): void
+    {
+        $dbRow = BackendUtility::getRecord('pages', 1);
+        unset($dbRow['sys_language_uid']);
+
+        $this->expectException(IncompleteRecordException::class);
+        $this->expectExceptionCode(1726046917);
+
+        $this->get(RecordFactory::class)->createFromDatabaseRow('pages', $dbRow);
+    }
+
+    #[Test]
+    public function throwsIncompleteRecordExceptionForMissingWorkspaceField(): void
+    {
+        $dbRow = BackendUtility::getRecord('pages', 1);
+        unset($dbRow['t3ver_oid']);
+
+        $this->expectException(IncompleteRecordException::class);
+        $this->expectExceptionCode(1726046918);
+
+        $this->get(RecordFactory::class)->createFromDatabaseRow('pages', $dbRow);
+    }
+
+    #[Test]
+    public function throwsIncompleteRecordExceptionForMissingSystemPropertyField(): void
+    {
+        $dbRow = BackendUtility::getRecord('pages', 1);
+        unset($dbRow['deleted']);
+
+        $this->expectException(IncompleteRecordException::class);
+        $this->expectExceptionCode(1726046919);
+
+        $this->get(RecordFactory::class)->createFromDatabaseRow('pages', $dbRow);
+    }
 }
diff --git a/typo3/sysext/core/Tests/Unit/Domain/RecordFactoryTest.php b/typo3/sysext/core/Tests/Unit/Domain/RecordFactoryTest.php
index 938ed168a9d6305cd9590a45f676b582bb021be9..77022492753daa19bb8cf2c27e40ed6df92c91cb 100644
--- a/typo3/sysext/core/Tests/Unit/Domain/RecordFactoryTest.php
+++ b/typo3/sysext/core/Tests/Unit/Domain/RecordFactoryTest.php
@@ -88,9 +88,9 @@ final class RecordFactoryTest extends UnitTestCase
         ]);
         $subject = new RecordFactory($schemaFactory, $this->createMock(RecordFieldTransformer::class));
         $recordObject = $subject->createFromDatabaseRow('foo', ['uid' => 1, 'pid' => 2, 'type' => 'foo', 'foo' => 'fooValue', 'bar' => 'barValue']);
-        self::assertFalse($recordObject->offsetExists('bar'));
-        self::assertTrue($recordObject->offsetExists('foo'));
-        self::assertTrue($recordObject->getRawRecord()->offsetExists('foo'));
-        self::assertTrue($recordObject->getRawRecord()->offsetExists('bar'));
+        self::assertFalse($recordObject->has('bar'));
+        self::assertTrue($recordObject->has('foo'));
+        self::assertTrue($recordObject->getRawRecord()->has('foo'));
+        self::assertTrue($recordObject->getRawRecord()->has('bar'));
     }
 }
diff --git a/typo3/sysext/frontend/Classes/DataProcessing/PageContentFetchingProcessor.php b/typo3/sysext/frontend/Classes/DataProcessing/PageContentFetchingProcessor.php
index b2b4b698e1ee172df135a371315f6b0aab0c544a..e0663761b22c43c5a2a10aa4202ac5e0ea11bde4 100644
--- a/typo3/sysext/frontend/Classes/DataProcessing/PageContentFetchingProcessor.php
+++ b/typo3/sysext/frontend/Classes/DataProcessing/PageContentFetchingProcessor.php
@@ -107,7 +107,7 @@ readonly class PageContentFetchingProcessor implements DataProcessorInterface
             );
             // 1b. Sort the records into the contentArea they belong to
             foreach ($flatRecords as $recordToSort) {
-                $colPosOfRecord = (int)$recordToSort['colPos'];
+                $colPosOfRecord = (int)$recordToSort->get('colPos');
                 $groupIdentifier = $contentAreasWithoutSlideMode[$colPosOfRecord]['identifier'];
                 $groupedContents[$groupIdentifier]['records'][] = $recordToSort;
             }
diff --git a/typo3/sysext/frontend/Classes/DataProcessing/RecordTransformationProcessor.php b/typo3/sysext/frontend/Classes/DataProcessing/RecordTransformationProcessor.php
index ba9a5d60e64a2067785ad94735308dd545cad612..b1d1e1709e66f852a0f00e7006e2f76462d37a46 100644
--- a/typo3/sysext/frontend/Classes/DataProcessing/RecordTransformationProcessor.php
+++ b/typo3/sysext/frontend/Classes/DataProcessing/RecordTransformationProcessor.php
@@ -104,6 +104,7 @@ readonly class RecordTransformationProcessor implements DataProcessorInterface
             $defaultTargetVariableName = 'record';
         }
         $targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration, $defaultTargetVariableName);
+        // @todo Should we make sure that $output is actually a Record object?
         $processedData[$targetVariableName] = $output;
         return $processedData;
     }