ORM 3.4.0 released with Native Lazy Objects and Property hooks support
Posted on
Last week we have released Doctrine 3.4.0 which primarily adds support for PHP 8.4 functionality:
From my perspective, this marks a new era for Doctrine ORM, one that can be compared with the invention of Reflection based mapping in Doctrine 2.0 way back in 2010.
For one, this now allows to use public properties for entities by default without having to fear consequences down the line. Expressed with our Doctrine tutorial example it looks like this:
1 <?php
#[ORM\Entity]
#[ORM\Table(name: 'bugs')]
class Bug
{
#[ORM\Id]
#[ORM\Column]
#[ORM\GeneratedValue]
public ?int $id = null;
#[ORM\Column]
public string $description;
#[ORM\Column]
public DateTime $created;
#[ORM\Column]
public string $status;
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'assignedBugs')]
public ?User $engineer = null {
get => $this->engineer;
set (?User $value) {
$value->assignedTo($this);
$this->engineer = $value;
}
}
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'reportedBugs')]
public ?User $reporter = null {
get => $this->reporter;
set (?User $value) {
$value->addReportedBug($this);
$this->reporter = $value;
}
}
public function __construct()
{
$this->created = new DateTime('now');
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
This reduces the boilerplate code for entities massively by getting rid of getters and setters.
Furthermore, with native lazy objects we do not have to resort to hacks anymore for public properties to work and this avoids the performance hit that was previously there.
Native lazy objects make lazy objects a breeze to implement on our end, it avoids code generation entirely and the overhead of using them is as minimal as it gets at runtime.
During the major version 3 cycle, you need to opt into native lazy objects via configuration:
Upgrade Path from 2.x for Lazy Proxies
Many of you are still on Doctrine ORM 2.x (~75% based on packagist installation numbers), so the question is how to upgrade.
With native lazy objects we have added a change that allows you to skip the migration to use lazy ghosts from Symfony VarExporter component.
Previously we thought migrating from our homegrown proxy library to Symfony would be the next step, but now we think you should directly move towards native lazy objects.
If you prepare to migrate to 3.4+ and run PHP 8.4 then we recommend that you skip using symfony/var-exporter
for lazy object generation and ignore the deprecation:
Then when you have prepared for all other deprecations and changes, you upgrade to 3.4.x and enable native lazy objects in one step.
This simplifies the migration by not having to migrate to different lazy object strategies multiple times.
General Upgrade Path from 2.x
With the re-adding of PARTIAL queries, the move towards native lazy objects the only two deprecations that we haven't fully addressed yet for a migration towards 3.x is
- the use of an argument for
EntityManager::flush($entity)
(#8459). Query::toIterable
is not a full replacement forQuery::iterate
(#9219)
Towards 4.0
This release is a first step towards ORM 4.0, which will require PHP 8.4 and is going to be built on native lazy objects functionality completely. Work on 4.0 has started now and we are hopeful to release it soon.
We have started planning our next hackathon in autumn, most likely a good chunk of work can be planned and completed then and a release could be right after or early next year.