Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-675

EntityManager->find() returns detached (or otherwise unmanaged) object.

    Details

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

      Description

      The find method seems to be broken. Returned objects are not managed according to the EntityManager. Fetching the same object via findAll() works.

      $e = $em->find('\net\jay\products\doctrine\ProductEntityType', 1);
      print "Class: " . get_class($e) . "<br>";
      print "Contained: " . ($em->contains($e) === true ? 'Yes' : 'No');
      

      This gives me:

      Class: net\jay\products\doctrine\ProductEntityType
      Contained: No

        Activity

        Hide
        Benjamin Eberlei added a comment -

        can you try to build a reproducible test-case? This would be a serious issue, however we cannot reproduce it this way.

        Show
        Benjamin Eberlei added a comment - can you try to build a reproducible test-case? This would be a serious issue, however we cannot reproduce it this way.
        Hide
        Michael Nielsen added a comment -

        Ah it turns out to be the leading namespace \ in the find parameter that killed me. Without it, the object turns out managed.

        Slightly troublesome that the object is returned in both cases perhaps.

        I tested with this added to tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php, in case the behaviour needs to be changed:

        public function testFind()
            {
            	// Create
                $user = new CmsUser;
                $user->name = 'Roman';
                $user->username = 'romanb';
                $user->status = 'developer';
                $this->_em->persist($user);
               
                $this->_em->flush();
                
                // Find1
                $this->_em->clear();
                $user2 = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $user->id);
                $this->assertTrue($this->_em->contains($user2));
        
                // Find2
                $this->_em->clear();
                $user3 = $this->_em->find('\Doctrine\Tests\Models\CMS\CmsUser', $user->id);
                $this->assertTrue($this->_em->contains($user3));
            }
        

        Find1 passes, while Find2 fails. The user is found in both cases though.

        Have a nice weekend.

        Show
        Michael Nielsen added a comment - Ah it turns out to be the leading namespace \ in the find parameter that killed me. Without it, the object turns out managed. Slightly troublesome that the object is returned in both cases perhaps. I tested with this added to tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php, in case the behaviour needs to be changed: public function testFind() { // Create $user = new CmsUser; $user->name = 'Roman'; $user->username = 'romanb'; $user->status = 'developer'; $ this ->_em->persist($user); $ this ->_em->flush(); // Find1 $ this ->_em->clear(); $user2 = $ this ->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $user->id); $ this ->assertTrue($ this ->_em->contains($user2)); // Find2 $ this ->_em->clear(); $user3 = $ this ->_em->find('\Doctrine\Tests\Models\CMS\CmsUser', $user->id); $ this ->assertTrue($ this ->_em->contains($user3)); } Find1 passes, while Find2 fails. The user is found in both cases though. Have a nice weekend.
        Hide
        Roman S. Borschel added a comment -

        That is because the objects are stored in the identity map based on their class name. We could strip off leading backslashes but once we start doing that we will always miss some places. Class names in strings are always fully-qualified, thus there is never a need to use a leading backslash in a string that contains a class name. The leading backslash is only useful in actual code, not in strings.

        Show
        Roman S. Borschel added a comment - That is because the objects are stored in the identity map based on their class name. We could strip off leading backslashes but once we start doing that we will always miss some places. Class names in strings are always fully-qualified , thus there is never a need to use a leading backslash in a string that contains a class name. The leading backslash is only useful in actual code, not in strings.
        Hide
        Michael Nielsen added a comment -

        Maybe just mentioning it in a "common use errors" section of the manual could be a good solution to avoid too much despair when the \ is added by mistake. If it's not already mentioned in there somewhere.

        Show
        Michael Nielsen added a comment - Maybe just mentioning it in a "common use errors" section of the manual could be a good solution to avoid too much despair when the \ is added by mistake. If it's not already mentioned in there somewhere.
        Hide
        Jan Obrátil added a comment -

        The solution is just add a warning when leading \ is found.

        The same bug happends to me. It took lots of hours to find that it was by \.

        Thanks
        obrys

        Show
        Jan Obrátil added a comment - The solution is just add a warning when leading \ is found. The same bug happends to me. It took lots of hours to find that it was by \. Thanks obrys
        Hide
        Roman S. Borschel added a comment -

        Fixed.

        Show
        Roman S. Borschel added a comment - Fixed.

          People

          • Assignee:
            Roman S. Borschel
            Reporter:
            Michael Nielsen
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: