---
title: "Feature: #96688 - Attributes for Extbase Annotations"
manual: "TYPO3 Core Changelog"
version: "main"
permalink: "https://docs.typo3.org/permalink/changelog:feature-96688"
source: "Changelog/12.0/Feature-96688-AttributesForExtbaseAnnotations.rst"
typo3-version: "12.0"
typo3-major: 12
type: "feature"
issue: 96688
forge: "https://forge.typo3.org/issues/96688"
tags: ["PHP-API", "ext:extbase"]
rendered: "2026-09-20T18:31:11+00:00"
---

# Feature: #96688 - Attributes for Extbase Annotations {#feature-96688}

See [forge#96688](https://forge.typo3.org/issues/96688)

## Description {#description}

Since PHP 8, native attributes are supported. In comparison to doc comments, attributes have auto-completion,
are better readable and were "invented" for storing meta-information about properties.
For more info on attributes see [https://stitcher.io/blog/attributes-in-php-8](https://stitcher.io/blog/attributes-in-php-8) and [https://www.php.net/manual/en/language.attributes.overview.php](https://www.php.net/manual/en/language.attributes.overview.php)

Extbase annotations are already nearly 1:1 translatable to attributes.

## Impact {#impact}

In addition to their usage as annotations, the following Extbase annotations have been enriched for usage as attributes:

```php
@Extbase\ORM\Transient
@Extbase\ORM\Cascade
@Extbase\ORM\Lazy
@Extbase\IgnoreValidation
@Extbase\Validate
```

### Examples {#examples}

#### Transient & Lazy {#transient-lazy}

Annotations:

```
use TYPO3\CMS\Extbase\Annotation as Extbase;

/**
 * @Extbase\ORM\Lazy()
 * @Extbase\ORM\Transient()
 */

```

Attributes:

```
use TYPO3\CMS\Extbase\Annotation as Extbase;

#[Extbase\ORM\Lazy()]
#[Extbase\ORM\Transient()]

```

#### Cascade {#cascade}

Annotation:

```
/**
 * @Extbase\ORM\Cascade("remove")
 */

```

Attribute:

```
#[Extbase\ORM\Cascade(['value' => 'remove'])]

```

#### Validate {#validate}

Annotations:

```
/**
 * @Extbase\Validate("StringLength", options={"minimum": 1, "maximum": 10})
 * @Extbase\Validate("NotEmpty")
 * @Extbase\Validate("TYPO3.CMS.Extbase:NotEmpty")
 * @Extbase\Validate("TYPO3.CMS.Extbase.Tests.Unit.Reflection.Fixture:DummyValidator")
 * @Extbase\Validate("\TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator")
 * @Extbase\Validate("TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator")
 */
protected $propertyWithValidateAnnotations;

```

Attributes:

```
#[Extbase\Validate(['validator' => 'StringLength', 'options' => ['minimum' => 1, 'maximum' => 10]])]
#[Extbase\Validate(['validator' => 'NotEmpty'])]
#[Extbase\Validate(['validator' => 'TYPO3.CMS.Extbase:NotEmpty'])]
#[Extbase\Validate(['validator' => 'TYPO3.CMS.Extbase.Tests.Unit.Reflection.Fixture:DummyValidator'])]
#[Extbase\Validate(['validator' => '\TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator'])]
#[Extbase\Validate(['validator' => NotEmptyValidator::class])]
protected $propertyWithValidateAttributes;

```

With promoted properties in constructor:

```
public function __construct(
    #[Extbase\Validate(['validator' => 'StringLength', 'options' => ['minimum' => 1, 'maximum' => 10]])]
    #[Extbase\Validate(['validator' => 'NotEmpty'])]
    #[Extbase\Validate(['validator' => 'TYPO3.CMS.Extbase:NotEmpty'])]
    #[Extbase\Validate(['validator' => 'TYPO3.CMS.Extbase.Tests.Unit.Reflection.Fixture:DummyValidator'])]
    #[Extbase\Validate(['validator' => '\TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator'])]
    #[Extbase\Validate(['validator' => NotEmptyValidator::class])]
    public readonly string $dummyPromotedProperty
)
{
    // your code here
}

```
