DDC-2909: different entity state after flush() #3624

Closed
opened 2026-01-22 14:24:11 +01:00 by admin · 2 comments
Owner

Originally created by @doctrinebot on GitHub (Jan 12, 2014).

Originally assigned to: @beberlei on GitHub.

Jira issue originally created by user jack88:

Example 1:

I add a new address to the repository and remove it before flush

$user = new User();
$user->setName('Mr. Test');

$address1 = new Address();
$address1->setCity('Hamburg');

//$user->addAddress($address1);
$em->persist($address1);
$em->persist($user);

echo "<br>Address entity state before remove:".$unitOfWork->getEntityState($address1);

$em->remove($address1);

echo "<br>Address entity state after remove:".$unitOfWork->getEntityState($address1)."<br>";

$em->flush();

echo "<br>Address entity state after flush:".$unitOfWork->getEntityState($address1);

Output:

Address entity state before remove:1 (MANAGED)
Address entity state after remove:2 (NEW)
Address entity state after flush:2 (NEW)

everything ok, new address entity was not stored and has the state NEW

Example 2:

now i add the address entity to the user entity (the addresses-property in user entity has cascade={"persist"})

I change a line

$user->addAddress($address1);
//$em->persist($address1);
$em->persist($user);

Output:

Address entity state before remove:1 (MANAGED)
Address entity state after remove:2 (NEW)
Address entity state after flush:1 (MANAGED)

Oops, my removed address is after flush() stored and managed?

I think I know what happened, but I do not think that's right. If I check the state of an entity before flush and the entity is in NEW state than i think it will not be stored.

"An entity is in NEW state if has no persistent state and identity and is not associated with an EntityManager"

My User & Address code:


class User {
    /*** @Id @Column(type="integer") @GeneratedValue ***/
    protected $id;
    /*** @Column(type="string") ***/
    protected $name;

    /****
     * @OneToMany(targetEntity="Address", mappedBy="user", cascade={"persist"})
     * @var Address[]
     ****/
    protected $addresses = null;

    public function **construct()
    {
        $this->addresses = new ArrayCollection();
    }

    public function getId() {
        return $this->id;
    }

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }

    public function addAddress(Address $address) {
        $this->addresses[] = $address;
        $address->setUser($this);
    }

    public function addAddresses(\Doctrine\Common\Collections\ArrayCollection $addresses) {
        $this->addresses = $addresses;
    }

    public function removeAddress(\Model\Address $address) {
        $this->addresses->removeElement($address);
        $address->removeUser();
    }

    /****
     * @return \Doctrine\Common\Collections\ArrayCollection
     */
    public function getAddresses() {
        return $this->addresses;
    }
} 


class Address {
    /*** @Id @Column(type="integer") @GeneratedValue ***/
    protected $id;
    /*** @Column(type="string") ***/
    protected $zipcode;
    /*** @Column(type="string") ***/
    protected $city;

    /****
     * @ManyToOne(targetEntity="User", inversedBy="addresses")
     * @var User;
     ****/
    protected $user = null;

    public function setCity($city) {
        $this->city = $city;
    }

    public function getCity() {
        return $this->city;
    }

    public function getId() {
        return $this->id;
    }

    public function setZipcode($zipcode) {
        $this->zipcode = $zipcode;
    }

    public function getZipcode() {
        return $this->zipcode;
    }

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

    public function removeUser() {
        $this->user = null;
    }

    public function getUser() {
        return $this->user;
    }
}
Originally created by @doctrinebot on GitHub (Jan 12, 2014). Originally assigned to: @beberlei on GitHub. Jira issue originally created by user jack88: Example 1: I add a new address to the repository and remove it before flush ``` $user = new User(); $user->setName('Mr. Test'); $address1 = new Address(); $address1->setCity('Hamburg'); //$user->addAddress($address1); $em->persist($address1); $em->persist($user); echo "<br>Address entity state before remove:".$unitOfWork->getEntityState($address1); $em->remove($address1); echo "<br>Address entity state after remove:".$unitOfWork->getEntityState($address1)."<br>"; $em->flush(); echo "<br>Address entity state after flush:".$unitOfWork->getEntityState($address1); ``` Output: Address entity state before remove:1 (MANAGED) Address entity state after remove:2 (NEW) Address entity state after flush:2 (NEW) everything ok, new address entity was not stored and has the state NEW Example 2: now i add the address entity to the user entity (the addresses-property in user entity has cascade={"persist"}) I change a line ``` $user->addAddress($address1); //$em->persist($address1); $em->persist($user); ``` Output: Address entity state before remove:1 (MANAGED) Address entity state after remove:2 (NEW) Address entity state after flush:1 (MANAGED) Oops, my removed address is after flush() stored and managed? I think I know what happened, but I do not think that's right. If I check the state of an entity before flush and the entity is in NEW state than i think it will not be stored. "An entity is in NEW state if has no persistent state and identity and is not associated with an EntityManager" My User & Address code: ``` class User { /*** @Id @Column(type="integer") @GeneratedValue ***/ protected $id; /*** @Column(type="string") ***/ protected $name; /**** * @OneToMany(targetEntity="Address", mappedBy="user", cascade={"persist"}) * @var Address[] ****/ protected $addresses = null; public function **construct() { $this->addresses = new ArrayCollection(); } public function getId() { return $this->id; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function addAddress(Address $address) { $this->addresses[] = $address; $address->setUser($this); } public function addAddresses(\Doctrine\Common\Collections\ArrayCollection $addresses) { $this->addresses = $addresses; } public function removeAddress(\Model\Address $address) { $this->addresses->removeElement($address); $address->removeUser(); } /**** * @return \Doctrine\Common\Collections\ArrayCollection */ public function getAddresses() { return $this->addresses; } } class Address { /*** @Id @Column(type="integer") @GeneratedValue ***/ protected $id; /*** @Column(type="string") ***/ protected $zipcode; /*** @Column(type="string") ***/ protected $city; /**** * @ManyToOne(targetEntity="User", inversedBy="addresses") * @var User; ****/ protected $user = null; public function setCity($city) { $this->city = $city; } public function getCity() { return $this->city; } public function getId() { return $this->id; } public function setZipcode($zipcode) { $this->zipcode = $zipcode; } public function getZipcode() { return $this->zipcode; } public function setUser(\Model\User $user) { $this->user = $user; } public function removeUser() { $this->user = null; } public function getUser() { return $this->user; } } ```
admin added the Bug label 2026-01-22 14:24:11 +01:00
admin closed this issue 2026-01-22 14:24:11 +01:00
Author
Owner

@doctrinebot commented on GitHub (Mar 23, 2014):

Comment created by @beberlei:

This is because you cascade persist. The feature is called "persist by reachability", which propagates managed state to related entities when cascade=persist is configured. Which it is in your case.

@doctrinebot commented on GitHub (Mar 23, 2014): Comment created by @beberlei: This is because you cascade persist. The feature is called "persist by reachability", which propagates managed state to related entities when cascade=persist is configured. Which it is in your case.
Author
Owner

@doctrinebot commented on GitHub (Mar 23, 2014):

Issue was closed with resolution "Invalid"

@doctrinebot commented on GitHub (Mar 23, 2014): Issue was closed with resolution "Invalid"
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#3624