New Release: Doctrine ORM 2.9 with Attributes, Typed Properties, more
Posted on
We have released a new minor version 2.9 of Doctrine ORM, the first version with support for using PHP 8 Attributes as a new driver for mapping entities and several other changes. See all changes and contributors in the Changelog on Github.
Attributes Mapping Driver
The following code example shows many of the mappings that are re-using the annotation classes for familiarity:
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping AS ORM;
#[ORM\Entity(repositoryClass: PostRepository::class)]
class Post
{
#[ORM\Column(type: Types::INTEGER)]
#[ORM\Id, ORM\GeneratedValue(strategy: 'AUTO')]
private ?int $id;
#[ORM\Column(type: Types::BOOLEAN)]
private bool $published = false;
#[ORM\Column(type: Types::SIMPLE_ARRAY)]
private array $text = [];
#[ORM\ManyToOne(targetEntity: User::class)]
public $author;
#[ORM\ManyToMany(targetEntity: Tag::class)]
#[ORM\JoinTable(name: "post_tags")]
#[ORM\JoinColumn(name: "post_id", referencedColumnName: "id")]
#[ORM\InverseJoinColumn(name: "tag_id", referencedColumnName: "id")]
public Collection $tags;
}
Typed Property Defaults
Since PHP 7.4 types can be declared on class properties and Doctrine now uses these type declarations to reduce amount of mapping boilerplate:
- Columns don't need the type definitions
- ManyToOne and OneToOne don't need target entity definitions
Example:
use Doctrine\ORM\Mapping AS ORM;
#[ORM\Entity(repositoryClass: UserRepository::class)]
class User
{
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
public ?int $id = null;
#[ORM\Column]
public \DateTime $created;
#[ORM\ManyToOne]
public Email $email;
}
Psalmified APIs
Improved the documentation to make sure static analysis tools and IDEs know
about the right entity classes returned from EntityManager
,
EntityRepository
and other public ORM APIs. This includes generics support
when you extend EntityRepository
.
use Doctrine\ORM\EntityRepository;
use App\Entity\User;
/**
* @template-extends EntityRepository<User>
*/
class UserRepository extends EntityRepository
{
}
Query::HINT_READ_ONLY
A new query hint is added that allows hydrating entities through DQL that are marked as read only for the unit of work session, as long as they are not yet loaded as writeable:
$dql = 'SELECT u FROM ' . ReadOnlyEntity::class . ' u WHERE u.id = ?1';
$query = $entityManager->createQuery($dql);
$query->setParameter(1, $user->id);
$query->setHint(Query::HINT_READ_ONLY, true);
$user = $query->getSingleResult();
Index/UniqueConstraints using Field Names
Instead of specifying column names for an index or unique-constraint declaration you can now alternatively use field names.
use Doctrine\ORM\Mapping AS ORM;
#[ORM\Entity]
#[ORM\Index(fields: ["isPublished"])]
class Post
{
#[ORM\Column]
public bool $isPublished = false;
}
This simplifies mapping as the column names passed through the naming strategy do not need to be known.
INDEX BY Associations
Previously DQL INDEX BY
was not possible for assocations, now you can:
$dql = 'SELECT p, u FROM Post INDEX BY p.author JOIN p.author u WHERE p.id = 3';
Deprecations
Doctrine ORM 2.9 rethinks deprecations and integrates with our new doctrine/deprecations library.
- Undeprecate
merge()
anddetach()
as no replacements are available yet - Notify Persist Change Tracking: Use Explicit Change Tracking instead
- DQL
SELECT PARTIAL
syntax, use Value Objects withSELECT NEW
instead EntityManager::flush()
with argumentsEntityManager::clear()
with arguments (use detach)- Named Queries in Mapping (use Repository)
cli-config.php
for console command configuration, injectEntityManagerProvider
instead.- Deprecate
doctrine/cache
for metadata caching, use PSR-6 cache instead
Cache Deprecations and PSR-6
Over the next versions we will deprecate use of doctrine/cache and replace it with PSR-6. If you are still using doctrine/cache code in your own application make sure to force the versions to "^1.10" in composer.json. Details
PHP 7.1 Support
ORM 2.9 reintroduces PHP 7.1 support, because it wasn't technically unsupported anyways. No changes were necessary to the code to allow it again except in the testsuite.
The PHP 7.1 support was re-added to allow a very broad approach to prepare for some of the deprecations that are introduced in ORM 2 and will be removed in version 3.0.
Coding Standard Support
Doctrine ORM 2.9 now supports and fully validates against Doctrine Coding Standard version 9.0+. This greatly improves automatic pull request checks as all new violations in a PR get caught and inlined into the PR as comments.