Skip to content

Loading…

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

Closed
doctrinebot opened this Issue · 2 comments

2 participants

@doctrinebot

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;
    }
}
@doctrinebot

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

Issue was closed with resolution "Invalid"

@beberlei beberlei was assigned by doctrinebot
@doctrinebot doctrinebot closed this
@doctrinebot doctrinebot added the Bug label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.