Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Invalid
    • Affects Version/s: Git Master
    • Fix Version/s: None
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      Hi. I am just now trying to convert a PHP project from Symfony 2.0 to Symfony 2.1. Then I also upgraded to the latest version of Doctrine, and I run into a severe problem.

      The application I am converting has two classes for users, one called "User" and the other called "UserName". They both inherit from "UserBase" and "UserName" is in fact an empty class that just inherit everything from "UserBase". Why do we have this setup? Because the "User" class is big and ugly with many dependencies form other tables in the database, and every time you load a "User" object it has to do a big join. And even then it has several collections that are lazy-loaded by Doctrine. In contrast "User Name" only contains name and e-mail, and is sufficient for most uses in the application.

      It was not possible to let "UserBase" be this lightweight user object, because it had to be declared as a mapped superclass, and a mapped superclass cannot be an entity. It functioned very well to let a lot of ManyToOne relationships in other classes be to the "UserName" entity, because then it only had to join one table, and it was fast. The full functionality of the "User" class we only need a few places.

      So, all was well and good, until I now got the task of porting the whole thing to the latest version of Symfony. What is wrong? I get the error message "Found entity of type User on association Object#Name, but expecting UserName". It is in the file UnitOfWork.php around line 740, and it makes my task impossible.

      In some cases I got a "User" object instead of "UserName" object that is declared in the "targetEntity". And that should be ok, because they come from the same table, and I only want to save the userId on the other object, and all "User" and "UserName" objects are directly form the database and not altered when I try to persist that other object.

      So, please, please, can you make the check a bit less restrictive? May be not just check if the entry is "instanceof" the "targetEntity", but allow it if the entity refers to the same table. Or only throw the exception if it is a new entity that needs to managed. Or make an annotation that makes it possible to switch this check off? I am a bit desperate here, because I really see no way around this. Thank you.

      1. Request.php
        10 kB
        Terje Bråten
      2. User.php
        18 kB
        Terje Bråten
      3. UserBase.php
        3 kB
        Terje Bråten
      4. UserName.php
        0.2 kB
        Terje Bråten

        Activity

        Hide
        Marco Pivetta added a comment -

        Unsupported usage of the ORM

        Show
        Marco Pivetta added a comment - Unsupported usage of the ORM
        Hide
        Marco Pivetta added a comment -

        Terje Bråten

        EntityManager#getReference

        returns proxies (when the entity is not already available)

        EntityManager#getPartialReference

        returns instances of your class with only the identifier set.

        Performance impact is negligible, since neither causes SQL to be thrown at your DB, but

        EntityManager#getPartialReference

        will produce instances incapable of lazy loading.

        Show
        Marco Pivetta added a comment - Terje Bråten EntityManager#getReference returns proxies (when the entity is not already available) EntityManager#getPartialReference returns instances of your class with only the identifier set. Performance impact is negligible, since neither causes SQL to be thrown at your DB, but EntityManager#getPartialReference will produce instances incapable of lazy loading.
        Hide
        Terje Bråten added a comment -

        Hi Marco,

        I guess my one unanswered question is the one about why it cannot be made configurable. Then both parties could be happy.

        So, what is the difference between $em->getReference($entity, $identifier)
        and $em->getPartialReference($entity, $identifier)?
        Is the latter one faster?

        Terje.

        Show
        Terje Bråten added a comment - Hi Marco, I guess my one unanswered question is the one about why it cannot be made configurable. Then both parties could be happy. So, what is the difference between $em->getReference($entity, $identifier) and $em->getPartialReference($entity, $identifier)? Is the latter one faster? Terje.
        Hide
        Marco Pivetta added a comment - - edited

        I personally think that double-checking at that location is a feature, and as Benjamin Eberlei exposed, it helps/helped a lot in avoiding hideous bugs (helped me too).

        Should not be removed. If your problem is mainly about performance and you know what you are doing, you can really go with partial objects. If you are sure that the objects already exist in your DB, you can even use things like

        $em->getReference($entity, $identifier)

        Does this fit your needs?

        Show
        Marco Pivetta added a comment - - edited I personally think that double-checking at that location is a feature, and as Benjamin Eberlei exposed, it helps/helped a lot in avoiding hideous bugs (helped me too). Should not be removed. If your problem is mainly about performance and you know what you are doing, you can really go with partial objects. If you are sure that the objects already exist in your DB, you can even use things like $em->getReference($entity, $identifier) Does this fit your needs?
        Hide
        Terje Bråten added a comment -

        I still do not like being ignored.

        Show
        Terje Bråten added a comment - I still do not like being ignored.

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Terje Bråten
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: