Skip to content

Loading…

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

Closed
doctrinebot opened this Issue · 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
@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.