Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-121

Persisting added children to parent in a one-to-many relationship fails

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-ALPHA3
    • Fix Version/s: 2.0-ALPHA3
    • Component/s: None
    • Security Level: All
    • Labels:
      None

      Description

      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.

        Activity

        Hide
        Roman S. Borschel added a comment -

        Improved formatting.

        Show
        Roman S. Borschel added a comment - Improved formatting.
        Hide
        Roman S. Borschel added a comment -

        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.

        Show
        Roman S. Borschel added a comment - 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.
        Hide
        Roman S. Borschel added a comment -

        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".

        Show
        Roman S. Borschel added a comment - 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".
        Hide
        Reinier Kip added a comment -

        Thanks a bundle!

        Show
        Reinier Kip added a comment - Thanks a bundle!

          People

          • Assignee:
            Roman S. Borschel
            Reporter:
            Reinier Kip
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: