Reputation: 36
I am trying to get the content of the One to Many author
attribute in my Strip
entity. The relation is between the Account
and the Strip
entities, bidirectional, and possessed by the Strip
entity.
Here is my code for both of them:
Strip.php
/**
* Strip
*
* @ORM\Table(name="strip")
* @ORM\Entity(repositoryClass="AppBundle\Repository\StripRepository")
*/
class Strip
{
//...
/**
*
* @ORM\ManyToOne(targetEntity="Account", inversedBy="strips")
* @ORM\JoinColumn(name="author_id", referencedColumnName="id")
*/
private $author;
//...
}
Account.php
/**
* Account
*
* @ORM\Table(name="account")
* @ORM\Entity(repositoryClass="AppBundle\Repository\AccountRepository")
*/
class Account
{
//...
/**
* @var array
*
* @ORM\OneToMany(targetEntity="Strip", mappedBy="author")
*/
private $strips;
public function __construct() {
$this->strips = new ArrayCollection();
}
//...
}
When I try to get the author
attribute from a strip
, I get an empty account
with the right id
, but empty on the other fields (username
, slug
, ...).
For example, here is what a dump($strip->getAuthor())
returns:
MyController.php on line 326:
Account {#773 ▼
+__isInitialized__: false
-id: 1
-username: null
-email: null
-emailIsPublic: 0
-password: null
-avatar: null
-biography: null
-level: 1
-registerDate: null
-strips: null
#slug: null
…2
}
Here are screenshots of my database showing that this relation is correctly registered:
Database screenshot strip table:
Database screenshot account table:
Upvotes: 2
Views: 1352
Reputation: 36
How I solved this problem
I did a custom joined query in StripRepository.php
to get both of the Account
and Strip
entities content:
StripRepository.php
class StripRepository extends \Doctrine\ORM\EntityRepository
{
public function findAuthors($strip)
{
$query = $this->getEntityManager()
->createQuery(
'SELECT s, a
FROM AppBundle:Strip s
JOIN s.author a
WHERE s.id = :id'
)
->setParameter('id', $strip);
try
{
return $query->getSingleResult();
}
catch (\Doctrine\ORM\NoResultException $e)
{
return null;
}
}
}
What was the problem ?
Doctrine2 uses lazy loading by default and so doing that allows to load all the content from both entities, instead of just loading the content from Strip
entity.
I read the Symfony documentation again about Doctrine associations where I found the example code I used:
Of course, if you know up front that you'll need to access both objects, you can [...] issue a join in the original query.
Joining Related Records - Symfony 3.4
Thanks to Mocrates who put me on the lead:
Or Better solution make a custom query in a StripRepository and select Author
Upvotes: 0
Reputation: 209
Doctrine2 use lazy loading.
Whenever you have a managed entity instance at hand, you can traverse and use any associations of that entity that are configured LAZY as if they were in-memory already. Doctrine will automatically load the associated objects on demand through the concept of lazy-loading
Hi it's a fetch lazy by Doctrine ... try to put in your :
/**
* @var array
*
* @ORM\OneToMany(targetEntity="Strip", mappedBy="author", fetch="EAGER")
*/
private $strips;
Or Better solution make a custom query in a StripRepository and select Author
$this->createQueryBuilder('s')
->addSelect('a')
->join('s.author', 'a')
Upvotes: 5