9

I have a Class like the following:

/** @Entity **/
class orgGroup{

    //id and stuff...

    /**
     * @Column(type="string")
     **/
    private $name;

    /**
     * @Column(type="string", nullable=true)
     **/
    private $description;

    /**
     * @ManyToOne(targetEntity="orgGroupType", inversedBy="_orgGroups")
     * @JoinColumn(name="_orgGroupType")
     **/

    private $_orgGroupType;

    //...
}

But when i load this Object from my database via

$groups = $em->getRepository("orgGroup")->findAll();

I just get the name correctly but not the _orgGroupType... and i dont know why... OrgGroup is the owner of orgGroupType and its just ONE object and not an array. My Webservice always just says:

{"error":[],"warning":[],"message":[],"data":[{"name":"AdministratorGroup","description":null,"_orgGroupType":{"__ isInitialized __":false}}]}

The result is:

"name":"AdministratorGroup",
"description":null,
"_orgGroupType":{"__ isInitialized __":false}

but should be:

"name":"AdministratorGroup",
"description":"some description",
"_orgGroupType":{name:"test"}

So there are 2 errors... and I have no idea why. All the data is set correctly in the database.

Any Ideas?

EDIT: Here's the missing code of my orgGroupType -entity

/** @Entity **/
class orgGroupType {
    /**
     * @OneToMany(targetEntity="orgGroup", mappedBy="_orgGroupType")
     **/
    private $_orgGroups;

    public function __construct()
    {
        $this->_orgGroups = new ArrayCollection();
    }
}
Laokoon
  • 1,241
  • 4
  • 24
  • 47

4 Answers4

33

Try to change fetch mode to EAGER.

@ORM\ManyToOne(targetEntity="****", fetch="EAGER"). 

It worked for me.

Praveen
  • 447
  • 5
  • 9
  • This is a bad idea if there is a lot of entities on the other side and you don't necessarily need them. They'll be loaded for no reason. – Benoit Duffez Jul 21 '21 at 21:11
21

This looks to me like a lazy-loading-issue. How do you get the data from the object into the Webservice answer?

Doctrine2 is lazy-loading if you don't configure something else, that means your $groups = $em->getRepository("orgGroup")->findAll(); won't return real orgGroup objects, but Proxy objects (Doctrine Documentation).

That means a $group object won't have it's description or orgGroupType value until you call $group->getDescription() or $group->getOrgGroupType() (then Doctrine loads them automatically), so you need to do that before writing the data into the JSON-response for the webservice. It won't work if you somehow loop through the object properties without using the getter methods.

I hope that was the problem :)

Manuel
  • 483
  • 3
  • 14
  • 1
    But whats the difference between accessing the property or calling a self-written getter method? – Laokoon Nov 19 '12 at 16:51
  • 3
    The Proxy classes inherit from your Entity classes and override your Getters - if you call them, they call a `_load` method or something like that and read the data you want from the database. If you just call `object->property`, there is no point where the Proxy class could initiate lazy-load. Here is a question with a similar problem: http://stackoverflow.com/questions/4090609/how-can-public-fields-break-lazy-loading-in-doctrine-2 – Manuel Nov 20 '12 at 13:40
  • 1
    @Manuel? How to did you solve the problem? There's also a problem regarding DoctrineCollection http://stackoverflow.com/questions/31971637/count-records-in-related-entity/31988152#31988152 – Danielle Rose Mabunga Aug 14 '15 at 23:17
  • 1
    Thank you for your answer ! I use Symfony since 3 years now and I didn't understand why sometimes my associations were empty... use the "get" function in Twig solved my problem. For example, instead of `{{ product.type.name }}` I wrote `{{ product.getType.name }}` – Eve Jun 25 '19 at 06:42
2
//Group.php ...

public function addUser(User $user): self
{
    if (!$this->users->contains($user)) {
        $this->users[] = $user;
        $user->addJoinedGroup($this);     /** VERY IMPORTANT **/
    }
    return $this;
}

Same in User.php Without it, it didn't do anything in my database

Elisha Senoo
  • 3,489
  • 2
  • 22
  • 29
TNP
  • 21
  • 1
  • 1
1

Be sure to initialize the orgGroups collection in the orgGroupType entity

/**
 * @OneToMany(targetEntity="orgGroup", mappedBy="_orgGroupType")
 */
protected $orgGroups ;

public function __construct() {
    $this->orgGroups = new ArrayCollection();
}

You might need to include the following in the Entity

use Doctrine\Common\Collections\Collection,
Doctrine\Common\Collections\ArrayCollection;
Pankrates
  • 3,074
  • 1
  • 22
  • 28
  • 1
    Thanks for the answer. But it doesnt solve my problem :(. I forgot to post the code of the orgGroupType-Class, but its implemented like you posted. I appended the missing code to my first post. Do you have any other ideas :-)? – Laokoon Nov 17 '12 at 15:00
  • 2
    __construct won't be called when you retrieve object from database – nikita2206 Nov 17 '12 at 15:12
  • 1
    Okay. One problem was, that my WebService function didnt packed the data correctly into my json-object. When I don't access the orgGroupType Object, it doesn't get initialized. But after i accessed it one time, i can easily pack it in... But the other problem with the description property is still unsolved. Its just a string and I just get "null" from the entityManager. In the Database my Object looks like: id: 1 name: AdministratorGroup description: some description _orgGroupType: 1 But the entityManager gives me: id: 1 name: AdministratorGroup description: null _orgGroupType: 1 – Laokoon Nov 17 '12 at 15:25