Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-132

Subclass' columns missing from cached ClassMetadata::$resultColumnNames

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.0-ALPHA3
    • Fix Version/s: 2.0-ALPHA4
    • Component/s: Mapping Drivers, ORM
    • Security Level: All
    • Labels:
      None

      Description

      I have a Customer with class table inheritance mapping and some fields, and a subclass called SuperCustomer with two fields: bool `isSuper` and string `extra`.

      I found that when replacing the usual ArrayCache with a MemcacheCache, everything works fine on the first request, but notices occur on subsequent requests:

      Notice: Undefined index: isSuper in X:\...\Doctrine\ORM\Persisters\StandardEntityPersister.php on line 577
      Notice: Undefined index: extra in X:\...\Doctrine\ORM\Persisters\StandardEntityPersister.php on line 577

      Inspection of ClassMetadata::$resultColumnNames on line 569 showed that the two fields `isSuper` and `extra` were (the only things) missing. The resulting object's `isSuper` and `extra` properties were empty.

      I have yet to find the cause of this, but maybe you have an idea.

      1. patch.diff
        14 kB
        Jonathan H. Wage

        Activity

        Hide
        Roman S. Borschel added a comment - - edited

        This is indeed strange. My first guess was that the resultColumnNames get lost during serialization but the ClassMetadata#__sleep implementation seems to be correct in so far as it returns the resultColumnNames field as part of the fields to serialize.

        Let me know as soon as you have more information.

        Btw. Which metadata driver are you using? Annotations?

        Show
        Roman S. Borschel added a comment - - edited This is indeed strange. My first guess was that the resultColumnNames get lost during serialization but the ClassMetadata#__sleep implementation seems to be correct in so far as it returns the resultColumnNames field as part of the fields to serialize. Let me know as soon as you have more information. Btw. Which metadata driver are you using? Annotations?
        Hide
        Reinier Kip added a comment - - edited

        > My first guess was that the resultColumnNames get lost during serialization
        This would be really strange, as the columns of the parent class Customer are still there after unserialization, so only a part is lost during serialization. My first guess was that the metadata is cached before the metadata loading is finished.

        > Which metadata driver are you using? Annotations?
        I'm using a custom metadata driver. Caching is separated from the driver, so the driver couldn't have anything to do with this, right?

        I'll try to find where it goes wrong and let you know.

        Show
        Reinier Kip added a comment - - edited > My first guess was that the resultColumnNames get lost during serialization This would be really strange, as the columns of the parent class Customer are still there after unserialization, so only a part is lost during serialization. My first guess was that the metadata is cached before the metadata loading is finished. > Which metadata driver are you using? Annotations? I'm using a custom metadata driver. Caching is separated from the driver, so the driver couldn't have anything to do with this, right? I'll try to find where it goes wrong and let you know.
        Hide
        Reinier Kip added a comment -

        First request:

        • Customer metadata is loaded and cached to Customer$CLASSMETADATA. $resultColumnNames contains Customer's fields.
        • SuperCustomer metadata is loaded and cached to SuperCustomer$CLASSMETADATA. $resultColumnNames contains Customer's and SuperCustomer's fields.
        • I request an object of class Customer be loaded from the database, which is an instance of SuperCustomer.
        • StandardEntityPersister::_createEntity() is called to create the entity, and uses Customer metadata ALSO CONTAINING SuperCustomer's $resultColumnNames.

        Second request:

        • Customer metadata is loaded from Customer$CLASSMETADATA. $resultColumnNames contains Customer's fields.
        • SuperCustomer metadata is loaded from SuperCustomer$CLASSMETADATA. $resultColumnNames contains Customer's and SuperCustomer's fields.
        • I request an object of class Customer be loaded from the database, which is an instance of SuperCustomer.
        • StandardEntityPersister::_createEntity() is called to create the entity, and uses Customer metadata NOT CONTAINING SuperCustomer's $resultColumnNames.

        Thought: the Customer's metadata is somehow changed after caching to cope with Customer's subclasses as well, but these changes are not in the cache. I don't have enough knowledge of Doctrine's internals, but you probably have a pretty good idea where this could happen.

        Show
        Reinier Kip added a comment - First request: Customer metadata is loaded and cached to Customer$CLASSMETADATA. $resultColumnNames contains Customer's fields. SuperCustomer metadata is loaded and cached to SuperCustomer$CLASSMETADATA. $resultColumnNames contains Customer's and SuperCustomer's fields. I request an object of class Customer be loaded from the database, which is an instance of SuperCustomer. StandardEntityPersister::_createEntity() is called to create the entity, and uses Customer metadata ALSO CONTAINING SuperCustomer's $resultColumnNames. Second request: Customer metadata is loaded from Customer$CLASSMETADATA. $resultColumnNames contains Customer's fields. SuperCustomer metadata is loaded from SuperCustomer$CLASSMETADATA. $resultColumnNames contains Customer's and SuperCustomer's fields. I request an object of class Customer be loaded from the database, which is an instance of SuperCustomer. StandardEntityPersister::_createEntity() is called to create the entity, and uses Customer metadata NOT CONTAINING SuperCustomer's $resultColumnNames. Thought: the Customer's metadata is somehow changed after caching to cope with Customer's subclasses as well, but these changes are not in the cache. I don't have enough knowledge of Doctrine's internals, but you probably have a pretty good idea where this could happen.
        Hide
        Roman S. Borschel added a comment -

        Thanks for your detailed information. I think I know what the issue is now. May be non-trivial to fix. I will try to look into it as soon as I got some free time.

        Show
        Roman S. Borschel added a comment - Thanks for your detailed information. I think I know what the issue is now. May be non-trivial to fix. I will try to look into it as soon as I got some free time.
        Hide
        Jonathan H. Wage added a comment -

        Here is a patch which fixes the issue but through doing this roman and I realized another issue.

        Show
        Jonathan H. Wage added a comment - Here is a patch which fixes the issue but through doing this roman and I realized another issue.
        Hide
        Roman S. Borschel added a comment -

        Scheduled for ALPHA4 as this may need some restructuring.

        Show
        Roman S. Borschel added a comment - Scheduled for ALPHA4 as this may need some restructuring.
        Hide
        Roman S. Borschel added a comment -

        This should be fixed now in trunk.

        Show
        Roman S. Borschel added a comment - This should be fixed now in trunk.

          People

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

            Dates

            • Created:
              Updated:
              Resolved: