Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1942

problem with serialize/merging entities with aggregation

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Duplicate
    • Affects Version/s: 2.2.2
    • Fix Version/s: None
    • Component/s: ORM
    • Labels:
    • Environment:
      linux, php 5.4.4, apache 2.2.22, mysql 5.5

      Description

      i have these two entities:

      namespace nuevo_paquete;

      class Clase_01{
      	/**
      	* @Id
      	* @Column(name="id",type="integer",nullable=false)
      	* @GeneratedValue
      	*/
      	protected $id;
              
              /**
      	* @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01", fetch="EXTRA_LAZY", cascade={"detach","merge"})
      	* @JoinColumn(name="clase_03", referencedColumnName="id")
      	*/
      	protected $clase_03;
      
              /**
      	* @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01_1", fetch="EXTRA_LAZY", cascade={"detach","merge"})
      	* @JoinColumn(name="clase_03_1", referencedColumnName="id")
      	*/
      	protected $clase_03_1;
      }
      
      namespace paquete_02;
      class Clase_03{
         /**
      	* @Id
      	* @Column(name="id",type="integer",nullable=false)
      	* @GeneratedValue
      	*/
      	protected $id;
      
              /**
      	* @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03", fetch="EXTRA_LAZY", cascade={"detach"})
      	*/
      	protected $clase_01;
      	
      	/**
      	* @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03_1", fetch="EXTRA_LAZY", cascade={"detach"})
      	*/
      	protected $clase_01_1;
      }
      

      Clase_01 have two aggregation association with Clase_03

      Clase_01 ------> Clase_03

      -----> Clase_03_1

      when serialize an object of class Clase_01 and then unserialize, i lost the reference to the object of class Clase_03
      but i can see Clase_03_1

      ej:

      $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
      $em->detach($aux_orm);
      $aux_s = serialize($aux_orm);
      $aux_orm = unserialize($aux_s);
      
      $aux_orm = $em->merge($aux_orm);
      echo '['.$aux_orm->getId().']'; // [1]
      echo '['.$aux_orm->getClase_03()->getId().']'; // [] expected : [1]
      echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
      

      when i call get_clase_03() before detach the object, i can see the object Clase_03
      ej:

      $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
      $aux_orm->getClase_03()->getId();
      
      $em->detach($aux_orm);
      $aux_s = serialize($aux_orm);
      $aux_orm = unserialize($aux_s);
      
      $aux_orm = $em->merge($aux_orm);
      echo '['.$aux_orm->getId().']'; // [1]
      echo '['.$aux_orm->getClase_03()->getId().']'; // [1]
      echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
      

        Activity

        gabriel sancho created issue -
        Hide
        gabriel sancho added a comment - - edited

        if i call $em->find() i still not able to view the object

        //----------------------------------------
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        $em->detach($aux_orm);
        $aux_s = serialize($aux_orm);
        $aux_orm = unserialize($aux_s);
        
        $aux_orm = $em->merge($aux_orm);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // [] expected : [1]
        echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
        
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // still empty [] expected : [1]
        

        //----------------------------------------
        and if i have another register referencing the same object of class_03, i can't view
        ej:

        $aux_orm = $em->find('nuevo_paquete\Clase_01', 2);
        echo '['.$aux_orm->getId().']'; // [2]
        echo '['.$aux_orm->getClase_03()->getId().']'; // still empty [] expected : [1]
        
        Show
        gabriel sancho added a comment - - edited if i call $em->find() i still not able to view the object //---------------------------------------- $aux_orm = $em->find('nuevo_paquete\Clase_01', 1); $em->detach($aux_orm); $aux_s = serialize($aux_orm); $aux_orm = unserialize($aux_s); $aux_orm = $em->merge($aux_orm); echo '['.$aux_orm->getId().']'; // [1] echo '['.$aux_orm->getClase_03()->getId().']'; // [] expected : [1] echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1] $aux_orm = $em->find('nuevo_paquete\Clase_01', 1); echo '['.$aux_orm->getId().']'; // [1] echo '['.$aux_orm->getClase_03()->getId().']'; // still empty [] expected : [1] //---------------------------------------- and if i have another register referencing the same object of class_03, i can't view ej: $aux_orm = $em->find('nuevo_paquete\Clase_01', 2); echo '['.$aux_orm->getId().']'; // [2] echo '['.$aux_orm->getClase_03()->getId().']'; // still empty [] expected : [1]
        Hide
        Marquez Alejandra added a comment -

        i have the same problem

        Show
        Marquez Alejandra added a comment - i have the same problem
        Hide
        Benjamin Eberlei added a comment -

        formatted code

        Show
        Benjamin Eberlei added a comment - formatted code
        Benjamin Eberlei made changes -
        Field Original Value New Value
        Description i have these two entities:

        namespace nuevo_paquete;
        class Clase_01{
        /**
        * @Id
        * @Column(name="id",type="integer",nullable=false)
        * @GeneratedValue
        */
        protected $id;
                
                /**
        * @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01", fetch="EXTRA_LAZY", cascade={"detach","merge"})
        * @JoinColumn(name="clase_03", referencedColumnName="id")
        */
        protected $clase_03;

                /**
        * @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01_1", fetch="EXTRA_LAZY", cascade={"detach","merge"})
        * @JoinColumn(name="clase_03_1", referencedColumnName="id")
        */
        protected $clase_03_1;
        ....
        }
        //------------------------------------------------
        ....
        //------------------------------------------------
        namespace paquete_02;
        class Clase_03{
           /**
        * @Id
        * @Column(name="id",type="integer",nullable=false)
        * @GeneratedValue
        */
        protected $id;

                /**
        * @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03", fetch="EXTRA_LAZY", cascade={"detach"})
        */
        protected $clase_01;

        /**
        * @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03_1", fetch="EXTRA_LAZY", cascade={"detach"})
        */
        protected $clase_01_1;
        }


        Clase_01 have two aggregation association with Clase_03

            Clase_01 ------> Clase_03
                     |-----> Clase_03_1

        when serialize an object of class Clase_01 and then unserialize, i lost the reference to the object of class Clase_03
        but i can see Clase_03_1

        ej:
        //----------------------------------------
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        $em->detach($aux_orm);
        $aux_s = serialize($aux_orm);
        $aux_orm = unserialize($aux_s);

        $aux_orm = $em->merge($aux_orm);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // [] expected : [1]
        echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
        //----------------------------------------


        when i call get_clase_03() before detach the object, i can see the object Clase_03
        ej:
        //----------------------------------------
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        $aux_orm->getClase_03()->getId();

        $em->detach($aux_orm);
        $aux_s = serialize($aux_orm);
        $aux_orm = unserialize($aux_s);

        $aux_orm = $em->merge($aux_orm);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
        //----------------------------------------

        i have these two entities:

        namespace nuevo_paquete;

        {code}
        class Clase_01{
        /**
        * @Id
        * @Column(name="id",type="integer",nullable=false)
        * @GeneratedValue
        */
        protected $id;
                
                /**
        * @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01", fetch="EXTRA_LAZY", cascade={"detach","merge"})
        * @JoinColumn(name="clase_03", referencedColumnName="id")
        */
        protected $clase_03;

                /**
        * @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01_1", fetch="EXTRA_LAZY", cascade={"detach","merge"})
        * @JoinColumn(name="clase_03_1", referencedColumnName="id")
        */
        protected $clase_03_1;
        ....
        }
        //------------------------------------------------
        ....
        //------------------------------------------------
        namespace paquete_02;
        class Clase_03{
           /**
        * @Id
        * @Column(name="id",type="integer",nullable=false)
        * @GeneratedValue
        */
        protected $id;

                /**
        * @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03", fetch="EXTRA_LAZY", cascade={"detach"})
        */
        protected $clase_01;

        /**
        * @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03_1", fetch="EXTRA_LAZY", cascade={"detach"})
        */
        protected $clase_01_1;
        }
        {code}

        Clase_01 have two aggregation association with Clase_03

            Clase_01 ------> Clase_03
                     |-----> Clase_03_1

        when serialize an object of class Clase_01 and then unserialize, i lost the reference to the object of class Clase_03
        but i can see Clase_03_1

        ej:

        {code}
        //----------------------------------------
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        $em->detach($aux_orm);
        $aux_s = serialize($aux_orm);
        $aux_orm = unserialize($aux_s);

        $aux_orm = $em->merge($aux_orm);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // [] expected : [1]
        echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
        //----------------------------------------
        {code}

        when i call get_clase_03() before detach the object, i can see the object Clase_03
        ej:

        {code}
        //----------------------------------------
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        $aux_orm->getClase_03()->getId();

        $em->detach($aux_orm);
        $aux_s = serialize($aux_orm);
        $aux_orm = unserialize($aux_s);

        $aux_orm = $em->merge($aux_orm);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
        //----------------------------------------
        {code}
        Hide
        Benjamin Eberlei added a comment -

        Can you paste a var_dump() of class1 after you call detach and before serialize and then another one after you called unserialize? Also a var_dump of the serialized string $aux_s

        Show
        Benjamin Eberlei added a comment - Can you paste a var_dump() of class1 after you call detach and before serialize and then another one after you called unserialize? Also a var_dump of the serialized string $aux_s
        Benjamin Eberlei made changes -
        Status Open [ 1 ] Awaiting Feedback [ 10000 ]
        gabriel sancho made changes -
        Attachment project_debug.log [ 11214 ]
        Hide
        gabriel sancho added a comment -

        var_dump in attached file

        Show
        gabriel sancho added a comment - var_dump in attached file
        gabriel sancho made changes -
        Status Awaiting Feedback [ 10000 ] In Progress [ 3 ]
        Hide
        gabriel sancho added a comment -

        i found that if the class has more than two levels have the same problem
        by ex. i have to do

        // class1 -> register id 1
        // class2 -> register id 1
        // class3 -> null, don't exist
        $class2 = $class1->getClass2();
        $class3 = $class2->getClass3();
        $class3->getId();
        

        otherwise doctrine insert new registers in database for class3
        after unserialize

        Show
        gabriel sancho added a comment - i found that if the class has more than two levels have the same problem by ex. i have to do // class1 -> register id 1 // class2 -> register id 1 // class3 -> null , don't exist $class2 = $class1->getClass2(); $class3 = $class2->getClass3(); $class3->getId(); otherwise doctrine insert new registers in database for class3 after unserialize
        Hide
        gonzalo added a comment -

        I have same problems

        Show
        gonzalo added a comment - I have same problems
        Hide
        gabriel sancho added a comment -

        if i declare in the entity annotation fetch="EAGER" works fine

        Show
        gabriel sancho added a comment - if i declare in the entity annotation fetch="EAGER" works fine
        Hide
        Valentin Claras added a comment - - edited

        I have the same problem.

        From what I saw, if I use fetch: EAGER, all my distinct entities are merged indeed, but if a specific entity (instance) is in two different collections, only one collection will have this instance.

        So, any news about this bug ?

        Show
        Valentin Claras added a comment - - edited I have the same problem. From what I saw, if I use fetch: EAGER, all my distinct entities are merged indeed, but if a specific entity (instance) is in two different collections, only one collection will have this instance. So, any news about this bug ?
        Hide
        Valentin Claras added a comment -

        I'm still trying to get my stuff works, and I'm now pretty sure that as soon as an object have to be merge more than once in a row (because of cascade associations), it end up being only in one collection, and lost for other entities.

        I hope this could help.

        Show
        Valentin Claras added a comment - I'm still trying to get my stuff works, and I'm now pretty sure that as soon as an object have to be merge more than once in a row (because of cascade associations), it end up being only in one collection, and lost for other entities. I hope this could help.
        Hide
        Marco Pivetta added a comment -

        I think this one is also related with DDC-1734 (noticed a lot of un-initialized objects).

        gabriel sancho can you please try initializing ALL of these related objects prior to detaching/serializing and repeat your checks?

        Show
        Marco Pivetta added a comment - I think this one is also related with DDC-1734 (noticed a lot of un-initialized objects). gabriel sancho can you please try initializing ALL of these related objects prior to detaching/serializing and repeat your checks?
        Marco Pivetta made changes -
        Assignee Benjamin Eberlei [ beberlei ] Marco Pivetta [ ocramius ]
        Marco Pivetta made changes -
        Status In Progress [ 3 ] Awaiting Feedback [ 10000 ]
        Hide
        gabriel sancho added a comment -

        How do I have to initialize the objects?

        Show
        gabriel sancho added a comment - How do I have to initialize the objects?
        Hide
        Marco Pivetta added a comment -

        gabriel sancho by calling any method that is not `getId` on them.
        This will initialize them

        Show
        Marco Pivetta added a comment - gabriel sancho by calling any method that is not `getId` on them. This will initialize them
        Hide
        Marco Pivetta added a comment -

        gabriel sancho news on this one? Managed to verify it?

        Show
        Marco Pivetta added a comment - gabriel sancho news on this one? Managed to verify it?
        Hide
        Marco Pivetta added a comment -

        This may be a duplicate of DDC-2306

        Show
        Marco Pivetta added a comment - This may be a duplicate of DDC-2306
        Hide
        Benjamin Eberlei added a comment -

        A related Github Pull-Request [GH-585] was closed
        https://github.com/doctrine/doctrine2/pull/585

        Show
        Benjamin Eberlei added a comment - A related Github Pull-Request [GH-585] was closed https://github.com/doctrine/doctrine2/pull/585
        Marco Pivetta made changes -
        Description i have these two entities:

        namespace nuevo_paquete;

        {code}
        class Clase_01{
        /**
        * @Id
        * @Column(name="id",type="integer",nullable=false)
        * @GeneratedValue
        */
        protected $id;
                
                /**
        * @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01", fetch="EXTRA_LAZY", cascade={"detach","merge"})
        * @JoinColumn(name="clase_03", referencedColumnName="id")
        */
        protected $clase_03;

                /**
        * @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01_1", fetch="EXTRA_LAZY", cascade={"detach","merge"})
        * @JoinColumn(name="clase_03_1", referencedColumnName="id")
        */
        protected $clase_03_1;
        ....
        }
        //------------------------------------------------
        ....
        //------------------------------------------------
        namespace paquete_02;
        class Clase_03{
           /**
        * @Id
        * @Column(name="id",type="integer",nullable=false)
        * @GeneratedValue
        */
        protected $id;

                /**
        * @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03", fetch="EXTRA_LAZY", cascade={"detach"})
        */
        protected $clase_01;

        /**
        * @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03_1", fetch="EXTRA_LAZY", cascade={"detach"})
        */
        protected $clase_01_1;
        }
        {code}

        Clase_01 have two aggregation association with Clase_03

            Clase_01 ------> Clase_03
                     |-----> Clase_03_1

        when serialize an object of class Clase_01 and then unserialize, i lost the reference to the object of class Clase_03
        but i can see Clase_03_1

        ej:

        {code}
        //----------------------------------------
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        $em->detach($aux_orm);
        $aux_s = serialize($aux_orm);
        $aux_orm = unserialize($aux_s);

        $aux_orm = $em->merge($aux_orm);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // [] expected : [1]
        echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
        //----------------------------------------
        {code}

        when i call get_clase_03() before detach the object, i can see the object Clase_03
        ej:

        {code}
        //----------------------------------------
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        $aux_orm->getClase_03()->getId();

        $em->detach($aux_orm);
        $aux_s = serialize($aux_orm);
        $aux_orm = unserialize($aux_s);

        $aux_orm = $em->merge($aux_orm);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
        //----------------------------------------
        {code}
        i have these two entities:

        namespace nuevo_paquete;

        {code}
        class Clase_01{
        /**
        * @Id
        * @Column(name="id",type="integer",nullable=false)
        * @GeneratedValue
        */
        protected $id;
                
                /**
        * @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01", fetch="EXTRA_LAZY", cascade={"detach","merge"})
        * @JoinColumn(name="clase_03", referencedColumnName="id")
        */
        protected $clase_03;

                /**
        * @ManyToOne(targetEntity="\paquete_02\Clase_03", inversedBy="clase_01_1", fetch="EXTRA_LAZY", cascade={"detach","merge"})
        * @JoinColumn(name="clase_03_1", referencedColumnName="id")
        */
        protected $clase_03_1;
        }
        {code}

        {code}
        namespace paquete_02;
        class Clase_03{
           /**
        * @Id
        * @Column(name="id",type="integer",nullable=false)
        * @GeneratedValue
        */
        protected $id;

                /**
        * @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03", fetch="EXTRA_LAZY", cascade={"detach"})
        */
        protected $clase_01;

        /**
        * @OneToMany(targetEntity="\nuevo_paquete\Clase_01", mappedBy="clase_03_1", fetch="EXTRA_LAZY", cascade={"detach"})
        */
        protected $clase_01_1;
        }
        {code}

        Clase_01 have two aggregation association with Clase_03

            Clase_01 ------> Clase_03
                     |-----> Clase_03_1

        when serialize an object of class Clase_01 and then unserialize, i lost the reference to the object of class Clase_03
        but i can see Clase_03_1

        ej:

        {code}
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        $em->detach($aux_orm);
        $aux_s = serialize($aux_orm);
        $aux_orm = unserialize($aux_s);

        $aux_orm = $em->merge($aux_orm);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // [] expected : [1]
        echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
        {code}

        when i call get_clase_03() before detach the object, i can see the object Clase_03
        ej:

        {code}
        $aux_orm = $em->find('nuevo_paquete\Clase_01', 1);
        $aux_orm->getClase_03()->getId();

        $em->detach($aux_orm);
        $aux_s = serialize($aux_orm);
        $aux_orm = unserialize($aux_s);

        $aux_orm = $em->merge($aux_orm);
        echo '['.$aux_orm->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03()->getId().']'; // [1]
        echo '['.$aux_orm->getClase_03_1()->getId().']'; // [1]
        {code}
        Marco Pivetta made changes -
        Status Awaiting Feedback [ 10000 ] In Progress [ 3 ]
        Hide
        Marco Pivetta added a comment -

        This issue is valid only before the fix introduced at DDC-2306. Duplicate confirmed

        Show
        Marco Pivetta added a comment - This issue is valid only before the fix introduced at DDC-2306 . Duplicate confirmed
        Marco Pivetta made changes -
        Status In Progress [ 3 ] Resolved [ 5 ]
        Resolution Duplicate [ 3 ]
        Marco Pivetta made changes -
        Security All [ 10000 ]
        Hide
        Doctrine Bot added a comment -

        A related Github Pull-Request [GH-585] was closed:
        https://github.com/doctrine/dbal/pull/585

        Show
        Doctrine Bot added a comment - A related Github Pull-Request [GH-585] was closed: https://github.com/doctrine/dbal/pull/585
        Hide
        Doctrine Bot added a comment -

        A related Github Pull-Request [GH-1172] was assigned:
        https://github.com/doctrine/doctrine2/pull/1172

        Show
        Doctrine Bot added a comment - A related Github Pull-Request [GH-1172] was assigned: https://github.com/doctrine/doctrine2/pull/1172

        This list may be incomplete, as errors occurred whilst retrieving source from linked applications:

        • Request to http://www.doctrine-project.org/fisheye/ failed: Error in remote call to 'FishEye 0 (http://www.doctrine-project.org/fisheye/)' (http://www.doctrine-project.org/fisheye) [AbstractRestCommand{path='/rest-service-fe/search-v1/crossRepositoryQuery', params={query=DDC-1942, expand=changesets[0:20].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

          People

          • Assignee:
            Marco Pivetta
            Reporter:
            gabriel sancho
          • Votes:
            3 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: