4

Relevant information: I'm using Symfony 2.8.x, Doctrine 2.4.8 and JMSSerializerBundle 1.0.

A Resource can have many Experiences. I'm making an API Call to retrieve a Resource and all associated Experiences.

However, the JSON I get back contains a null on $resource on the Experience entity.

I'm using the the following method to retrieve the Resource:

$this->findBy([], [], $limit, $offset);

I don't believe this should be an issue because I've tried setting the fetch mode to EAGER directly in the annotations - this still hasn't worked. I've also cleared the cache.

Resource.orm.yml

oneToMany:
    experiences:
        targetEntity: Experience
        mappedBy: resource
        fetch: EAGER

Experience.orm.yml

resource:
    targetEntity: Resource
    inversedBy: experiences
    joinColumn:
        name: resource_id
        referencedColumnName: id
        fetch: EAGER
    fetch: EAGER

See I've tried ALL the eager fetches!!

Response

The response I get when making an API request for this json:

{
    "resources": [{
        "id": 1,
        # SNIP #
        "experiences": [{
            "resource": null,
            "id": 1,
            # SNIP #
        }]
    }]
}

Note the null for resource!

Here's why I think it's a problem with lazy loading: the collection is an instance of Doctrine\ORM\PersistentCollection instead of just an array as I expect:

enter image description here

Why is this null?? What is my problem? Have I:

  • Messed up the relationship configuration and this isn't actually anything to do with lazy loading
  • Placed lazy loading in the wrong place
  • Misunderstood and this is a good thing because of recursion?
  • Something else retarded?
Jimbo
  • 25,790
  • 15
  • 86
  • 131

3 Answers3

1

This is probably the normal behavior for the API and its Serializer (model to JSON transformation).

Why would you need experiences.resource to be filled actually ? You already have it on the root level of the JSON.

If you still want experiences to fully contain their resource, you probably have to configure the Serializer and force it to go 1 step deeper in serialization. But most of the time, Serializers are configured this way to avoid infinite cycles (resource containing its experiences, containing its resource, containing its experiences, and so on..

VaN
  • 2,180
  • 4
  • 19
  • 43
  • Yeah I thought this might be something to do with avoiding that recursion (as one of my bullet points suggets).. – Jimbo Nov 30 '16 at 17:23
  • if your API is based on Symfony too, it probably uses the native Serializer or JMS Serializer. In both cases, I'm pretty sure you can configure the level of recursion for serialization. But do it only if you really need to. Most of the time, the default recursion level fits common needs. – VaN Nov 30 '16 at 17:28
0

Maybe you need to upgrade Doctrine 2.4.8 to 2.5

Doctrine2 in ZF2 - DQL gives different result than findOneBy method

> "doctrine/doctrine-module":"dev-master",
> "doctrine/doctrine-orm-module": "dev-master",
> "doctrine/dbal":"2.5.*@dev",
> "doctrine/orm": "2.5.*@dev",

[UPDATE]

Getting a "true" object from a proxy object in doctrine2

Aize
  • 510
  • 3
  • 10
0

One away to force Doctrine retrieve all related entities is creating a dql containing this entities.

$dql = "Select r, e From \MyNamespace\ToEntity\Resource r 
         Join r.experiences e";

$entityManager->createQuery($dql)->execute();
Vinícius Fagundes
  • 1,983
  • 14
  • 24