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

Closed
opened 2026-01-22 12:28:51 +01:00 by admin · 5 comments
Owner

Originally created by @doctrinebot on GitHub (Nov 6, 2009).

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.

Originally created by @doctrinebot on GitHub (Nov 6, 2009). 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.
admin added the Bug label 2026-01-22 12:28:51 +01:00
admin closed this issue 2026-01-22 12:28:52 +01:00
Author
Owner

@doctrinebot commented on GitHub (Nov 6, 2009):

Comment created by romanb:

Improved formatting.

@doctrinebot commented on GitHub (Nov 6, 2009): Comment created by romanb: Improved formatting.
Author
Owner

@doctrinebot commented on GitHub (Nov 7, 2009):

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 commented on GitHub (Nov 7, 2009): 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.
Author
Owner

@doctrinebot commented on GitHub (Nov 7, 2009):

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 commented on GitHub (Nov 7, 2009): 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".
Author
Owner

@doctrinebot commented on GitHub (Nov 8, 2009):

Issue was closed with resolution "Fixed"

@doctrinebot commented on GitHub (Nov 8, 2009): Issue was closed with resolution "Fixed"
Author
Owner

@doctrinebot commented on GitHub (Nov 9, 2009):

Comment created by reinier.kip:

Thanks a bundle!

@doctrinebot commented on GitHub (Nov 9, 2009): Comment created by reinier.kip: Thanks a bundle!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#155