[PR #420] Cascade dependent identities to associations #8166

Closed
opened 2026-01-22 15:58:43 +01:00 by admin · 0 comments
Owner

Original Pull Request: https://github.com/doctrine/orm/pull/420

State: closed
Merged: No


Currently when an entity in a one-to-one association gets its identity from another entity it requires calling the setter for the associated entity from the setter in the identity source entity setter or passing the identity source entity to the associated entity's constructer, something similar to this:

<?php
/**
 * @Entity
 */
class User
{
    /** @Id @Column(type="integer") @GeneratedValue */
    private $id;

    /** @OneToOne(targetEntity="Address", mappedBy="user", cascade={"persist"}) */
    private $address;

    public setAddress(Address $address)
    {
        $this->address = $address;
        $address->setUser($this); // Calling setter in associated entity
    }
}

/**
 * @Entity
 */
class Address
{
    /** @Id @OneToOne(targetEntity="User", inversedBy="address") */
    private $user;

    __construct(User $user)
    {
        $this->user = $user; // Passing identity source to constructor
    }

    public setUser(User $user)
    {
        $this->user = $user;
    }
}

$user = new User();
$em->persist($user);
$em->flush();

$address = new Address($user); // If using constructor
$user->setAddress($address);
// OR
$user->setAddress(new Address()); // If using setter

$em->flush();

This PR adds checks for associations with cascade persist that have dependent identities which are empty, and sets the field in the associated entity to the identity source entity. Granted it's not complicated to do as the previous example, but this allows for simpler code. It also seems a logical assumption that when the association is cascade persist this should happen automatically:

<?php
/**
 * @Entity
 */
class User
{
    /** @Id @Column(type="integer") @GeneratedValue */
    private $id;

    /** @OneToOne(targetEntity="Address", mappedBy="user", cascade={"persist"}) */
    private $address;

    public setAddress(Address $address)
    {
        $this->address = $address;
    }
}

/**
 * @Entity
 */
class Address
{
    /** @Id @OneToOne(targetEntity="User", inversedBy="address") */
    private $user;

    // This could be removed if not needed
    public setUser(User $user)
    {
        $this->user = $user;
    }
}

$user = new User();
$em->persist($user);
$em->flush();

$user->setAddress(new Address());

$em->flush();

Now only if it wasn't so wordy to explain :)

**Original Pull Request:** https://github.com/doctrine/orm/pull/420 **State:** closed **Merged:** No --- Currently when an entity in a one-to-one association gets its identity from another entity it requires calling the setter for the associated entity from the setter in the identity source entity setter or passing the identity source entity to the associated entity's constructer, something similar to this: ``` php <?php /** * @Entity */ class User { /** @Id @Column(type="integer") @GeneratedValue */ private $id; /** @OneToOne(targetEntity="Address", mappedBy="user", cascade={"persist"}) */ private $address; public setAddress(Address $address) { $this->address = $address; $address->setUser($this); // Calling setter in associated entity } } /** * @Entity */ class Address { /** @Id @OneToOne(targetEntity="User", inversedBy="address") */ private $user; __construct(User $user) { $this->user = $user; // Passing identity source to constructor } public setUser(User $user) { $this->user = $user; } } $user = new User(); $em->persist($user); $em->flush(); $address = new Address($user); // If using constructor $user->setAddress($address); // OR $user->setAddress(new Address()); // If using setter $em->flush(); ``` This PR adds checks for associations with cascade persist that have dependent identities which are empty, and sets the field in the associated entity to the identity source entity. Granted it's not complicated to do as the previous example, but this allows for simpler code. It also seems a logical assumption that when the association is cascade persist this should happen automatically: ``` php <?php /** * @Entity */ class User { /** @Id @Column(type="integer") @GeneratedValue */ private $id; /** @OneToOne(targetEntity="Address", mappedBy="user", cascade={"persist"}) */ private $address; public setAddress(Address $address) { $this->address = $address; } } /** * @Entity */ class Address { /** @Id @OneToOne(targetEntity="User", inversedBy="address") */ private $user; // This could be removed if not needed public setUser(User $user) { $this->user = $user; } } $user = new User(); $em->persist($user); $em->flush(); $user->setAddress(new Address()); $em->flush(); ``` Now only if it wasn't so wordy to explain :)
admin added the pull-request label 2026-01-22 15:58:43 +01:00
admin closed this issue 2026-01-22 15:58:43 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#8166