I have a User entity with a self-referencing one-to-many relationship - Every User owns a set of students (who are also users):
<?php
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\Common\Collections\ArrayCollection;
/**
* User
*/
class User extends BaseUser
{
/**
* #var int
*/
protected $id;
private $students;
// ....
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
public function __construct() {
$this->students = new ArrayCollection();
// ...
parent::__construct();
}
/**
* Remove student
*
* #return User
*/
public function removeStudent($student)
{
$this->students->removeElement($student);
return $this;
}
/**
* Add a student
*
* #param User $students
*
* #return User
*/
public function addStudent($student)
{
$this->students->add($student);
return $this;
}
/**
* Get students
*
* #return User
*/
public function getStudents()
{
$this->students;
}
/**
* Set students
*
* #param User $students
*
* #return User
*/
public function setStudents($students)
{
$this->students = $students;
return $this;
}
// ....
}
The mapping is done as a one-to-many unidirectional with join table
AppBundle\Entity\User:
type: entity
table: null
repositoryClass: AppBundle\Repository\UserRepository
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
// ...
manyToMany:
students:
targetEntity: User
joinTable:
name: mentors_students
joinColumns:
mentor_id:
referencedColumnName: id
inverseJoinColumns:
student_id:
referencedColumnName: id
unique: true
lifecycleCallbacks: { }
Now when I add/edit a user using the EasyAdmin bundle, I can add the students for that user. However, when I retrieve the entity, the students property is always null. For example, when I view the list of users:
Here the user 'sagarl3232' is supposed to be a student of 'sj' but the view above clearly shows the property when retrieved is null.
The entity is persisted correctly in the database. That is, the join table has the right values:
Why is Doctrine doing this to me? Isn't it supposed to hydrate the students array automatically?
Your getter doesnt return anything!
/**
* Get students
*
* #return User[]
*/
public function getStudents()
{
return $this->students;
}
BTW why you should adjust the docblock too. The getter is supposed to return an array User[]
Related
I have a manyToMany relation beetween "Lot" and "BailProprietaire"
When i get an entity "BailProprietaire", i see the entities "lot" linked
But when i get an entity "Lot", i don't see entities "BailProprietaire" linked
In lot.orm.yml, i have :
AppBundle\Entity\Lot:
type: entity
repositoryClass: AppBundle\Repository\LotRepository
table: lot
....
....
manyToMany:
bauxProprietaire:
targetEntity: BailProprietaire
mappedBy: lots
In bailProprietaire.orm.yml, i have :
AppBundle\Entity\BailProprietaire:
type: entity
table: bail_proprietaire
repositoryClass: AppBundle\Repository\BailProprietaireRepository
....
....
manyToMany:
lots:
targetEntity: Lot
inversedBy: bauxProprietaire
fetch: LAZY
joinTable:
name: bail_proprietaire_lots
joinColumns:
bail_id:
referencedColumnName: id
inverseJoinColumns:
lot_id:
referencedColumnName: id
lifecycleCallbacks: { }
do you see something i miss ?
thanks
EDIT : Add php entity code
Lot.php
class Lot
{
/**
* #var integer
*/
private $id;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $bauxProprietaire;
/**
* Constructor
*/
public function __construct()
{
$this->bauxProprietaire = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add bauxProprietaire
*
* #param \AppBundle\Entity\BailProprietaire $bauxProprietaire
*
* #return Lot
*/
public function addBauxProprietaire(\AppBundle\Entity\BailProprietaire $bauxProprietaire)
{
$this->bauxProprietaire[] = $bauxProprietaire;
return $this;
}
/**
* Remove bauxProprietaire
*
* #param \AppBundle\Entity\BailProprietaire $bauxProprietaire
*/
public function removeBauxProprietaire(\AppBundle\Entity\BailProprietaire $bauxProprietaire)
{
$this->bauxProprietaire->removeElement($bauxProprietaire);
}
/**
* Get bauxProprietaire
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBauxProprietaire()
{
return $this->bauxProprietaire;
}
}
BailProprietaire.php
class BailProprietaire
{
/**
* #var integer
*/
private $id;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $lots;
/**
* Constructor
*/
public function __construct()
{
$this->lots = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add lot
*
* #param \AppBundle\Entity\Lot $lot
*
* #return BailProprietaire
*/
public function addLot(\AppBundle\Entity\Lot $lot)
{
$this->lots[] = $lot;
return $this;
}
/**
* Remove lot
*
* #param \AppBundle\Entity\Lot $lot
*/
public function removeLot(\AppBundle\Entity\Lot $lot)
{
$this->lots->removeElement($lot);
}
/**
* Get lots
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getLots()
{
return $this->lots;
}
}
EDIT 2 : in fact, it works but not with the listener
in fact i see the entities "BailProprietaire" when i get a "lot" but when i flush data, i have a listener. In this listener, i call a virtual propertie of "Lot.php" where i have :
if (!empty($this->bauxProprietaire)) {
....
} else {
....
}
but $this->bauxProprietaire is always empty
Ok, i found the problem.
When i do $this->bauxProprietaire, i have a "Doctrine\ORM\PersistentCollection" but when i look the collection in this object, there is 0 element
but if i do $this->bauxProprietaire->toArray(), i see my relation
I don't understand why but it works
It's possible to have an entity that looks like this code, and when I would like to instantiate this entity, the dossierClientActif properties are automatically a filter of dossiersClient properties.
class Contact {
private id;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $dossiersClient;
/**
* #var \AppBundle\Entity\DossierClient
*/
private $dossierClientActif;
/**
* #return \Doctrine\Common\Collections\ArrayCollection
*/
public function getDossiersClient()
{
return $this->dossiersClient;
}
/**
* Add dossierClient
*
* #param \AppBundle\Entity\DossierClient $dossierClient
*
* #return Contact
*/
public function addDossierClient(\AppBundle\Entity\DossierClient $dossierClient)
{
$this->dossiersClient[] = $dossierClient;
return $this;
}
/**
* #return DossierClient
*/
public function getDossierClientActif()
{
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('indArchive', 0));
return $this->dossiersClient->matching($criteria)->first();
}
}
Use JMS serializer with virtual properties works for me.
AppBundle\Entity\Contact:
exclusion_policy: ALL
virtual_properties:
getDossierClientActif:
serialized_name: dossierClientActif
groups: ['contact']
properties:
id:
expose: true
groups: ['contact']
dossiersClient:
expose: true
groups: ['contact']
I have a problem related to Doctrine2:
1- I have two tables joining on a many-to-one relation:
Table 1 - Activity
The Schema:
Backend\adminBundle\Entity\Activity:
type: entity
table: activity
indexes:
result_id:
columns:
- result_id
id:
id:
type: integer
nullable: false
unsigned: false
comment: ''
id: true
generator:
strategy: IDENTITY
fields:
......
manyToOne:
result:
targetEntity: Actionresult
cascade: { }
mappedBy: null
inversedBy: null
joinColumns:
result_id:
referencedColumnName: id
orphanRemoval: false
The Entity
<?php
namespace Backend\adminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Activity {
/**
* #var \Backend\adminBundle\Entity\Actionresult
*
* #ORM\ManyToOne(targetEntity="Backend\adminBundle\Entity\Actionresult")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="result_id", referencedColumnName="id")
* })
*/
private $result;
/**
* #var \Backend\adminBundle\Entity\SfGuardUser
*
* #ORM\ManyToOne(targetEntity="Backend\adminBundle\Entity\SfGuardUser")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
/* There are other Properties */
/**
* Set result
*
* #param \Backend\adminBundle\Entity\Actionresult $result
* #return Activity
*/
public function setResult(\Backend\adminBundle\Entity\Actionresult $result = null)
{
$this->result = $result;
return $this;
}
/**
* Get result
*
* #return \Backend\adminBundle\Entity\Actionresult
*/
public function getResult()
{
return $this->result;
}
}
Table 2 - Actionresult Related to Activity Table by Id:
The schema:
Backend\adminBundle\Entity\Actionresult:
type: entity
table: actionresult
id:
id:
type: integer
nullable: false
unsigned: false
comment: ''
id: true
generator:
strategy: IDENTITY
fields:
name:
type: string
nullable: false
length: 255
fixed: false
comment: ''
lifecycleCallbacks: { }
The Entity:
<?php
namespace Backend\adminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Actionresult
*
* #ORM\Table(name="actionresult")
* #ORM\Entity
*/
class Actionresult
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Actionresult
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
The Question:
With doctrine i can refer from table Activity to Actionresult with the name result.
How can i refer with doctrine from table Actionresult to Activity??
Thank you in advance.
To be thorough, you should try and stick to one type of entity mapping in Symfony whenever possible. The #ORM* annotations are redundant if you use YAML config, and vice-versa. I'll provide the answer using YAML, and I believe you'll be able to convert to annotations if need be.
# Activity.yml
Activity:
type: entity
...
manyToOne:
result:
targetEntity: ActionResult
inversedBy: activities
# ActionResult.yml
Result:
type: entity
oneToMany:
activities:
targetEntity: Activity
mappedBy: result
# ActionResult.php
class Result {
protected $activities;
public function __construct()
{
$this->activities = new Doctrine\Common\Collections\ArrayCollection();
}
public function getActivities()
{
return $this->activities;
}
public function addActivity(Activity $activity)
{
$activity->setResult($this);
$this->activities->add($activity);
}
public function removeActivity(Activity $activity)
{
$activity->setResult(null);
$this->activities->removeElement($activity);
}
}
# Activity.php
class Activity {
protected $result;
public function getResult()
{
return $this->result;
}
public function setResult(ActionResult $result = null)
{
$this->result = $result;
}
}
Reference:
Bidirectional one to many: http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-bidirectional
I am trying to work out why I can't access the name (or any attribute) of the parent entity of my Category entity. My view works fine and displays all the attributes other than the parent information.
What I am looking for is the name (i.e. "Interior") of the parent, rather than the ID. But I can't seem to access it.
namespace AyrshireMinis\CarBundle\Entity;
class Category
{
/**
* #var integer
*/
protected $id;
/**
* #var integer
*/
protected $parent_id;
/**
* #var Category
*/
protected $parent;
public function __construct() {}
/**
* #return int
*/
public function getParentId()
{
return $this->parent_id;
}
public function getParent()
{
return new self($this->parent_id);
}
}
My Doctrine entity mapping:
fields:
parent_id:
type: integer
length: 11
nullable: true
In my Twig template I am attempting to pull out the parent category's name like this:
<td>
{{ category.parent.name }}
</td>
However, I get no error but no category name either.
This is a brief view of my SQL GUI:
The table is hierarchical.
public function getParent()
{
return new self($this->parent_id);
}
What you are doing here is creating a new category with all properties blank. Take a look at the symfony and doctrine documentation to learn how to create relationships properly.
I ended up resolving this by removing the parent_id from my ORM mapping and replacing it with this:
manyToOne:
parent:
targetEntity: AyrshireMinis\CarBundle\Entity\Category
inversedBy: children
Then added these member variables to my Category entity class:
/**
* #var Category
*/
private $children;
/**
* #var Category
*/
private $parent;
I try to save related entities User and Profile. I use the cascade={"persist"} option. Data saves properly in Database except user_id field in Profile table, its equal to null. When i turn relations profile_id field in User table saves properly. Where is my mistake? Here is my relations:
User entity:
/**
* #ORM\OneToOne(targetEntity="Profile", mappedBy="user", ,cascade={"persist"})
*/
Profile entity:
/**
* #ORM\OneToOne(targetEntity="User", inversedBy="profile", cascade={"persist"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
Getters & setters:
User:
` /**
* #param Profile $profile
*/
public function setProfile(Profile $profile)
{
$this->profile = $profile;
}
/**
* #return Profile
*/
public function getProfile()
{
return $this->profile;
}`
Profile:
`/**
* #param User $user
*/
public function setUser(User $user)
{
$this->user = $user;
}
/**
* #return User
*/
public function getUser()
{
return $this->user;
}`
This is essentially #skler answer but I couldn't explain myself in comments.
Try doing this in your User.php's setProfile():
public function setProfile(Profile $profile)
{
$this->profile = $profile;
$this->profile->setUser($this);
}
Maybe you add only profile in user: $user->addProfile($profile); and you didn't the viceversa: $profile->addUser($user);