Hi everyone and thanks for help,
I'm currently dealing with a problem while I want to make an OneToMany/ManyToOne Bidirectional Relationship with Doctrine2 (& Symfony2.5.6).
Here are my two classes : Voiture , and Voiture modeles
namespace Esprit\ParcBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Voiture
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $serie;
/**
* #ORM\Column(type="date")
*/
private $dateM;
/**
* #ORM\Column(type="string")
*/
private $marque;
/**
* #ORM\Column(type="integer")
* #ORM\ManyToOne(targetEntity="ModeleVoiture")
* #ORM\JoinColumn(referencedColumnName="id")
*/
private $id_m;
and :
<?php
namespace Esprit\ParcBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class ModeleVoiture
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
*#ORM\Column(type="string")
*/
private $libelle;
/**
* #ORM\Column(type="string")
*/
private $pays;
when i want to phpmyadmin to check if the foreign key relationis added or no, i can't find it
thank you for your help.
You need to remove #ORM\Column(type="integer") from private $id_m;
Related
I have 3 tables, Articles, ArticlesTree, fieldsi18n...
my current code has OnoToOne relationship between fieldsi18n and the other 2 entities.
So my fieldsi18n's table has one column to the articles_id and other for the tree_id... how can I accomplish this with just one column that will be named to element_id
How can i use the DiscriminatorColumn ?
HexFieldI18n:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\HexFieldI18nRepository")
*/
class HexFieldI18n
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="App\Entity\HexArticlesTree", mappedBy="label", cascade={"persist", "remove"})
*/
private $tree;
/**
* #ORM\OneToOne(targetEntity="App\Entity\HexArticles", mappedBy="label", cascade={"persist", "remove"})
*/
/**
* #ORM\OneToOne(targetEntity="App\Entity\HexArticles", mappedBy="label", cascade={"persist", "remove"})
*/
private $article;
}
HexArticles
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\HexArticlesRepository")
*/
class HexArticles
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="App\Entity\HexFieldI18n", inversedBy="article", cascade={"persist", "remove"})
*/
private $label;
}
HexArticlesTree
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\HexArticlesTreeRepository")
*/
class HexArticlesTree
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="App\Entity\HexFieldI18n", inversedBy="article", cascade={"persist", "remove"})
*/
private $label;
}
Any ideas?
Thanks
I don't undertand just one column that will be named to element_id. Doctrine has several annotations like #InheritanceType to determinate the inheranceType SINGLE_TABLE or JOINED. I only have used SINGLE_TABLE inheritance that basicly has columns to determinate its entity, which are saved in the column that you mark with #DiscrimatorType annotation, you must remember that entities will not be persisting to the database, only acts like a descriminator.
Is it possible to keep an array of entities A in the entity A ? How to do this with Doctrine ?
I have :
class A {
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $sisters;
}
But I don't know what to add to have Doctrine do what I need.
A can have many sisters, and many sisters can be sister of A (Many-To-Many, Self-referencing):
/**
* #ORM\Entity()
* #ORM\Table()
*/
class A
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\A")
*/
private $sisters;
}
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-self-referencing
I am working on a project where there I am forced to use cascade={"remove","persist"} because of the problem described here.
Reading through the documentation, to quote:
Even though automatic cascading is convenient it should be used with care. Do not blindly apply cascade=all to all associations as it will unnecessarily degrade the performance of your application. For each cascade operation that gets activated Doctrine also applies that operation to the association, be it single or collection valued.
And I see that the same can be fixed if I use
$em->persist($entity);
In my persistence services, which I am already calling. However, doctrine doesn't work as expected. Here are my entities.
Entity/Employee.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping AS ORM;
/**
* #ORM\Entity
* #ORM\Table(uniqueConstraints={#ORM\UniqueConstraint(
* name="UNIQ_EMPLOYEE_ID_NAME_ADDRESS_STATE_CITY_COUNTRY",
* columns={"id","name","city","state","country"}
* )})
*/
class Employee
{
/**
* #ORM\Id
* #ORM\Column(type="integer", options={"unsigned":true})
* #ORM\GeneratedValue(strategy="NONE")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $name;
/**
* #ORM\Column(type="text", nullable=false)
*/
private $address;
/**
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $city;
/**
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $state;
/**
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $country;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Department", inversedBy="employee", cascade={"remove","persist"})
* #ORM\JoinColumn(name="department_id", referencedColumnName="id", nullable=false)
*/
private $department;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Transfer", mappedBy="employee", cascade={"remove","persist"})
*/
private $transfer;
}
?>
Entity/Department.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping AS ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Selectable;
/**
* #ORM\Entity
* #ORM\Table(uniqueConstraints={#ORM\UniqueConstraint(
* name="UNIQ_DEPARTMENT_ID_NAME",
* columns={"id","name"}
* )})
*/
class Department
{
/**
* #ORM\Id
* #ORM\Column(type="integer", options={"unsigned":true})
* #ORM\GeneratedValue(strategy="NONE")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Employee", mappedBy="department", cascade={"remove","persist"})
*/
private $employee;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Transfer", mappedBy="department", cascade={"remove","persist"})
*/
private $transfer;
}
?>
Entity/Transfer.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping AS ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Selectable;
/**
* #ORM\Entity
* #ORM\Table(uniqueConstraints={#ORM\UniqueConstraint(
* name="UNIQ_TRANSFER_ID_DEPARTMENT_EMPLOYEE_START_END",
* columns={"id","name"}
* )})
*/
class Transfer
{
/**
* #ORM\Id
* #ORM\Column(type="integer", options={"unsigned":true})
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="date", length=255, nullable=false)
*/
private $start;
/**
* #ORM\Column(type="date", length=255, nullable=false)
*/
private $end;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Employee", inversedBy="attendance", cascade={"persist","remove"})
* #ORM\JoinColumn(name="employee_id", referencedColumnName="id", nullable=false)
*/
private $employee;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Department", inversedBy="attendance", cascade={"persist","remove"})
* #ORM\JoinColumn(name="department_id", referencedColumnName="id", nullable=false)
*/
private $department;
}
?>
UPDATE 1:
Now, I have another problem. Since my GeneratorValue strategy for Employee and Department are NONE, I have problem with duplicate record error. I am trying to use PreFlushEventArgs to remove the entity before persisting if the record exists in database. But I wonder if it should be that complex?
Thanks for your help in advance.
It seems you cascade persist operation from Employee to Department and Transfer. But they do cascade the persist operation to the Employee Entity too.
It means when you do
$em->persist($an_employee);
You are stuck in a persist loop.
In my opinion, the cascade persist should be only in one way, i.e. only on the Employee entity.
Also if you choose to do this, add your Department to the Employee, and not the opposite :
$an_employee->addDepartment($a_department);
$an_employee->addTransfer($a_transfer);
That way, when you persist an employee, its Departments and Transfer should be persisted too
I have two entities relating to this issue, and I want a join table to be able to cross reference values in each table.
Here is an explanation:
Entity ContainerType.php:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Entity\Containers;
/**
* ContainerType
*
* #ORM\Table(name="container_type")
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
*/
class ContainerType
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="type", type="string", length=255)
*/
private $type;
/**
* #var \DateTime
*
* #ORM\Column(name="date_added", type="datetime")
*/
private $dateAdded;
/**
* #var \DateTime
*
* #ORM\Column(name="date_modified", type="datetime", nullable=true)
*/
private $dateModified;
/**
* #ORM\ManyToMany(targetEntity="Containers", inversedBy="type")
* #ORM\JoinTable(name="container_type_containers")
**/
private $container;
public function __construct()
{
$this->container = new ArrayCollection();
}
And entity Containers.php:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Entity\ContainerType;
/**
* Containers
*
* #ORM\Table(name="containers")
* #ORM\Entity
*/
class Containers
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="number", type="string", length=255)
*/
private $number;
/**
* #ORM\ManyToMany(targetEntity="Containers", mappedBy="container")
*/
private $type;
public function __construct()
{
$this->type = new ArrayCollection();
}
And although the schema update works without problems, when I do a doctrine:schema:validate I get the following fail:
[Mapping] FAIL - The entity-class 'AppBundle\Entity\Containers' mapping is invalid:
* The association AppBundle\Entity\Containers#type refers to the owning side field AppBundle\Entity\Containers#container which does not exist.
But the $container field DOES exist in ContainerType so I do not understand why it's trying to reference a field called container in the Containers entity?
Can anyone shed any light on this?
Thank you
Michael
I think this code should works fine for you :)
ContainerType.php
/**
* #ORM\ManyToMany(targetEntity="Containers", inversedBy="containersType")
* #ORM\JoinTable(name="container_type_containers",
* joinColumns={#ORM\JoinColumn(name="container_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="container_type_id", referencedColumnName="id")})
*/
protected $containers;
Containers.php
/**
* #ORM\ManyToMany(targetEntity="ContainerType", mappedBy="containers")
*/
protected $containersType;
I have just realized my error!
I had used the wrong target Entity in the Containers.php file, I should have used ContainerType as the target, instead I had Containers which is why it was trying to find the field in the wrong table!
Profile Entity
<?php
namespace Student\ProfileBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Profile
*
* #ORM\Table(name="sf2_profile")
* #ORM\Entity(repositoryClass="Student\ProfileBundle\Entity\ProfileRepository")
*/
class Profile
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="Contact", mappedBy="profile")
*/
protected $contact;
Contact Entity:
<?php
namespace Student\ContactBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Contact
*
* #ORM\Table(name="sf2_contact")
* #ORM\Entity(repositoryClass="Student\ContactBundle\Entity\ContactRepository")
*/
class Contact
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="Profile", inversedBy="contact")
* #ORM\JoinColumn(name="profile_id", referencedColumnName="id")
*/
protected $profile;
When I update schema via command line i received the following error message
The target entity Student\ProfileBundle\Entity\Contact can not found in Student\ProfileBundle\Entity\Profile#contact
Please help me .
There is a namespace error - entities are located in different bundles. You should provide an absolute path to entity instead of relative:
for Profile#contact relation:
/**
* #ORM\OneToOne(targetEntity="Student\ContactBundle\Entity\Contact", mappedBy="profile")
*/
protected $contact;
and for Contact#profile one:
/**
* #ORM\OneToOne(targetEntity="Student\ProfileBundle\Entity\Profile", inversedBy="contact")
* #ORM\JoinColumn(name="profile_id", referencedColumnName="id")
*/
protected $profile;