DDC-121: Persisting added children to parent in a one-to-many relationship fails #1816

Closed
doctrinebot opened this Issue Nov 6, 2009 · 5 comments

1 participant

@doctrinebot

Jira issue originally created by user reinier.kip:

Affects Doctrine 2.0 at revision 6679 (trunk).

Persisting children that were added to a parent retrieved from the database in (at least) a one-to-many relationship fails when the children array was not initialized before adding. A simple demonstration:

/*** @Entity **/
class Customer {
    /*** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") **/
    public $id;
    /*** @OneToMany(targetEntity="User", mappedBy="customer", cascade={"persist"}) **/
    public $users = array();
}

/*** @Entity **/
class User {
    /*** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") **/
    public $id;
    /*** @ManyToOne(targetEntity="Customer") @JoinColumn(name="customerId", referencedColumnName="id") **/
    public $customer;
}

Let's retrieve our existing customer and add a user to it.

$customer = $em->find('Customer', 1);
$user = new User();
$user->customer = $customer;
$customer->users[] = $user;
$em->persist($customer);
$em->flush();

At this point the user has not been persisted.
When initializing the users collection by e.g.:

$customer = $em->find('Customer', 1);
sizeof($customer->users);
$user = new User();

... this is not the case.

@doctrinebot

Comment created by romanb:

Improved formatting.

@doctrinebot

Comment created by romanb:

I fixed your example, UnitOfWork#_doPersist was using foreach() on the PersistentCollection so that it was initialized. That should not happen.

At the same time I think there might still be the issue of new objects in collections being wiped out when the collection is initialized. So I still need to look into that.

@doctrinebot

Comment created by romanb:

By the way: In your example you do not even need to call $em->persist($customer); because $customer is managed and $user is a new object attached to it (in the collection). Together with cascade={"persist"} this means it will be persisted automatically. This is called "persistence by reachability".

@doctrinebot

Issue was closed with resolution "Fixed"

@doctrinebot

Comment created by reinier.kip:

Thanks a bundle!

@doctrinebot doctrinebot added this to the 2.0-ALPHA3 milestone Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment