Getting a “true” object from a proxy object in doctrine2

前端 未结 11 1429
南笙
南笙 2021-02-01 13:50

Doctrine uses proxy objects to represent related objects in order to facilitate lazy loading. This is a really cool feature, but its causing an issue with something I am trying

相关标签:
11条回答
  • 2021-02-01 14:26

    Edit: As mention by @flu this approach don't return the "true" object. However it can be useful in case if you need the data from the object. Then, you can just get the real object from ObjectManager by some of identity.


    We can use __load() method from Proxy interface

    $proxyObject->__load();
    
    0 讨论(0)
  • 2021-02-01 14:26

    This is a little bit nasty workaround that issue :

    // $proxyObject = ...
    
    $em->detach($proxyObject);
    $entityObject = $em->find(<ENTITY_CLASS>, $proxyObject->getId());
    
    // now you have real entity and not the proxy (entityObject instead of proxyObject)
    

    after that you can replace proxy reference if you need to have it inside other entities

    0 讨论(0)
  • 2021-02-01 14:33

    Here is my solution:

    Context:

    All my entities have id property and getId() method


    Solution:

    $em = $this->getDoctrine()->getManager();
    
    // 1 -> get the proxy object class name
    $proxy_class_name = get_class($proxyObject);
    
    // 2 -> get the real object class name
    $class_name = $em->getClassMetadata($proxy_class_name)->rootEntityName;
    
    // 3 -> get the real object
    $object = $em->find($class_name, $proxyObject->getId());
    

    Problem:

    This solution don't work if id property and getId() method are in a Trait class

    I hope that it can help someone

    0 讨论(0)
  • 2021-02-01 14:34

    The Symfony PropertyNormalizer gets around this issue using the ReflectionClass getParent method. If you need to inspect the object, as for a normalizer, rather than just use the ->get methods, you should be able to use a similar approach.

    It appears the Proxy has a parent of the actual entity, which is why instanceof still works.

    0 讨论(0)
  • 2021-02-01 14:41

    @mustaccio, @Heather Orr

    I had this problem. Thanks for idea,

    This is the code:

    // $object is a Proxy class
    $objectClass = get_class($object);
    $reflectionClass = new \ReflectionClass($objectClass);
    
    // Make sure we are not using a Proxy class
    if ($obj instanceof Proxy) {
        $reflClass = $reflClass->getParentClass();
    }
    

    Another way, if you just need to read annotations:

    // $object is a Proxy class
    $objectClass = get_class($object);
    $classMetadata = $this->em->getClassMetadata($objectClass);
    
    foreach ($classMetadata->getReflectionProperties() as $property) {
        $annotation = $this->annotationReader->getPropertyAnnotation($property, YOUR_ANNOTATION::class)
    }
    

    Not absolutely related to original question, but I hope this will help some people...

    0 讨论(0)
  • 2021-02-01 14:41

    If you first used $em->getReference and then $em->find, then the result will be a _proxy. I recommend using:

     createQueryBuilder ... ->getQuery()
        ->setHint (Query::HINT_FORCE_PARTIAL_LOAD, true)
        ->getOneOrNullResult();
    
    0 讨论(0)
提交回复
热议问题