I am new to Doctrine2 and trying to create entities for the following DB structure:
I want to have all machine parts as an array in one attribute of the machine class. I tried this:
class Machine {
....
/**
* #var array
* #ORM\OneToMany(targetEntity="MachineHasPart", mappedBy="machine", cascade={"persist", "remove"}, orphanRemoval=TRUE)
*/
private $parts;
....
public function getParts () {
return array_map(
function ($machineHasPart) {
return $machineHasPart->getPart();
},
$this->parts->toArray()
);
}
}
Where MachineHasPart is a #MappedSuperclass for the intermediate entities/tables (like machineHasCylinder etc), but it failed with:
An exception occurred while executing 'SELECT FROM machineHasPart t0'.
Should I restructure my database to use ORM here? Or there is a solution for my case?
You cannot query a #MappedSuperClass. This is also mentioned in the Doctrine2 documentation in chapter 6.1. Mapped Superclasses:
A mapped superclass cannot be an entity, it is not query-able and persistent
This means you have to either change the target entity to something queryable or you have to make MachineHasPart to a entity and change to single table inheritance.
When I look at your database structure I would suggest changing your Machine entity to have three independent relationships for the parts. One for Belt, one for Cylinder and one for Gear.
Then instead of a generic getParts you will have three methods getBelts, getCylinders and getGears.
If that is really not what you want then you can leave a comment.
UPDATE
You can solve it also with class inheritance. First make a base class Part that is also an entity and use it in the other classes Belt, Cylinder and Gear:
Part:
<?php
namespace Machine\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Part
*
* #ORM\Entity
* #ORM\Table("part")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="discriminator", type="string")
* #ORM\DiscriminatorMap({
* "part" = "Part",
* "gear" = "Gear",
* "cylinder" = "Cylinder",
* "belt" = "Belt",
* })
* #property int $id
*/
class Part
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var Machine
* #ORM\ManyToOne(targetEntity="Machine\Entity\Machine", inversedBy="parts")
* #ORM\JoinColumn(name="machine_id", referencedColumnName="id", nullable=true)
*/
protected $machine;
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* #param int $id
* #return self
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
//... add setters and getters for machine as normal ...
}
Extend this class in your other parts:
Belt:
<?php
namespace Machine\Entity;
/**
* Belt
*
* #ORM\Entity
*/
class Belt extends Part
{
}
Cylinder:
<?php
namespace Machine\Entity;
/**
* Cylinder
*
* #ORM\Entity
*/
class Cylinder extends Part
{
}
Gear:
<?php
namespace Machine\Entity;
/**
* Gear
*
* #ORM\Entity
*/
class Gear extends Part
{
}
Now in your machine relate to the parts like as follows.
Machine:
<?php
namespace Machine\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Machine
*
* #ORM\Entity
* #ORM\Table("machine")
* #property int $id
*/
class Machine
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* #param int $id
* #return self
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #var Collection
* #ORM\OneToMany(targetEntity="Machine\Entity\Part", mappedBy="machine")
*/
protected $parts;
public function __constuct()
{
$parts = new ArrayCollection();
}
/**
*
* #return Collection
*/
public function getParts()
{
return $this->parts;
}
//... add setters and getters for parts as normal ...
}
Extend this class in your other parts:
Reading further in the Doctrine2 documentation in chapter 6.1. Mapped Superclasses (referred to by #Wilt):
... Furthermore Many-To-Many associations are only possible if the mapped superclass is only used in exactly one entity at the moment...
This means in this case the ORM mapping doesn't help. I cannot gather the data of all three entities MachineHasCylinder, MachineHasBelt and MachineHasGear through a MappedSupperclass at the same time.
I think using DQL or Native SQL is the only solution for this problem.
Related
I am new to Symfony and trying to setup entities and relationships. Even though I seemed to have correctly annotated the primary keys.
When running
php bin/console doctrine:schema:validate
I got an error as follows:
The referenced column name 'brandId' has to be a primary key column on the target entity class 'AppBundle\Entity\Brands'.
The entities look like ( only relevant portions):
Thanks
Brands
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="brands")
*/
class Brands
{
/**
* #ORM\Id
* #ORM\Column(type="smallint",length=3,unique=true,options={"unsigned":true})
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $brandId;
/**
* one brands has many models
* #ORM\OneToMany(targetEntity="Models", mappedBy="brandId")
* #ORM\JoinColumn(name="brandId", referencedColumnName="brandId")
*/
private $models;
public function __construct()
{
$this->models = new ArrayCollection();
}
Models:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\ModelsRepository")
* #ORM\Table(name="models")
*/
class Models
{
/**
* #ORM\Column(type="smallint",length=4,unique=true,options={"unsigned":true})
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $modelId;
/**
* #ORM\Column(type="string", length=25)
*/
private $model;
/**
* Many models for one brand
* #ORM\ManyToOne(targetEntity="Brands",inversedBy="models")
* #ORM\JoinColumn(name="brandId", referencedColumnName="brandId")
*/
private $brandId;
A valid and clean entity mapping should be something like:
Brand.php
/**
* #ORM\Entity
* #ORM\Table(name="brands")
*/
class Brand
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* one brands has many models
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Model", mappedBy="brand")
*/
private $models;
public function __construct()
{
$this->models = new ArrayCollection();
}
}
Model.php
class Model
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #ORM\Column(type="string", length=25)
*/
private $name;
/**
* Many models for one brand
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Brand",inversedBy="models")
*/
private $brand;
}
for clean and easy usage:
$brand->getId(); //get id of brand
$brand->getModels(); //get array of Model object, ArrayCollection
$model->getBrand()->getId(); // Get id of related brand of some model
$model->getBrand()->getName(); //get the name of other propery of related brand
In your Brands model, this annotation should not be present.
* #ORM\JoinColumn(name="brandId", referencedColumnName="brandId")
JoinColumn only applies to ManyToOne and OneToOne fields. This is because in a one to many relationship, there will not be a join column in the table that contains the data for the owning ("one") side of the relationship.
JoinColumn is for defining a column on the "many" side that identifies which record on the "one" side owns it, so including it in the Models model is okay.
Wrong answer removed...
Bonus tips: Entity classes or better their instances should represent single datasets of a table. So their names should be singular ;)
By chosing not prefixed names for your primary key columns, you can spare some code, because Doctrine can work its magic then.
Also you should not prefix one column with the table name, if you do not prefix all of them.
This all ended up being an issue with Doctrine's naming strategy, which I did not know about. See this article for details
That strategy was set as default, while I was trying to adapt mysql's underscore naming strategy to PHP's camel case naming strategy. This was causing Symfony not to find the primary and thus the error.
Once I learned about that and with the valuable input I've received with this post, I have refactored the entities as below:
Thank you all.
Brands
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="brands")
*/
class Brands
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="smallint",length=3,unique=true,options={"unsigned":true})
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* one brands has many models
*
* #ORM\OneToMany(targetEntity="Models", mappedBy="brandId")
*/
private $models;
public function __construct()
{
$this->models = new ArrayCollection();
}
/**
* #ORM\Column(type="string", length=25)
*/
private $brand;
.......
}
Models
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\ModelsRepository")
* #ORM\Table(name="models")
*/
class Models
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="smallint",length=4,unique=true,options={"unsigned":true})
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=25)
*/
private $model;
/**
* Many models for one brand
* #ORM\ManyToOne(targetEntity="Brands",inversedBy="models")
* #ORM\JoinColumn(name="brand_id", referencedColumnName="id")
*/
private $brandId;
/**
* Many models for one segment
* #ORM\ManyToOne(targetEntity="Segments", inversedBy="models")
* #ORM\JoinColumn(name="segment_id", referencedColumnName="id")
*/
private $segmentId;
.....
}
I have recently startet with Zend Framework 2 and came now across Doctrine 2, which I would now like to integrate in my first project.
I have now got the following situation and even after days, I can not find a solution.
I have 3 Tables:
Advert
advert_id
advert_title
etc
Category
category_id
name
label
etc
advert2category
advert2category_category_id
advert2category_advert_id
An Advert can be in different Categories and different Categories have different Adverts, therefore the table Advert2Category (ManytoMany).
After reading through the www, I have decided that it should be a ManytoMany Bidirectional, with the "owning side" at the Advert Entity.
Don't ask me why I decided that, I still don't understand Doctrine fully. Anyway, I created 3 Entities, but guess I only need Advert and Category Entity.
I now want the following to happen.
I click on a Category and want to see a list of Articles within this category., that means I have to read out the Table advert2category. I have created the Entities, here my Advert Entity:
So here is first my Advert Entity:
namespace Advert\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Advert
*
* #ORM\Table(name="advert")
* #ORM\Entity
*/
class Advert
{
/**
* #var integer
*
* #ORM\Column(name="advert_id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $advertId;
/**
* #var string
*
* #ORM\Column(name="advert_title", type="string", length=255, nullable=true)
*/
private $advertTitle;
/**
* #ORM\ManyToMany(targetEntity="Category", inversedBy="advertCategory", cascade={"persist"})
* #ORM\JoinTable(name="advert2category",
* joinColumns={#ORM\JoinColumn(name="advert2category_category_id", referencedColumnName="category_id")},
* inverseJoinColumns={#ORM\JoinColumn(name="advert2category_advert_id", referencedColumnName="advert_id")}
* )
*/
protected $category;
public function __construct()
{
$this->category = new ArrayCollection();
}
/**
* Get advertId
*
* #return integer
*/
public function getAdvertId()
{
return $this->advertId;
}
/**
* Set advertTitle
*
* #param string $advertTitle
* #return Advert
*/
public function setAdvertTitle($advertTitle)
{
$this->advertTitle = $advertTitle;
return $this;
}
/**
* Get advertTitle
*
* #return string
*/
public function getAdvertTitle()
{
return $this->advertTitle;
}
/**
* Set category
*
* #param \Advert\Entity\User $category
* #return Advert
*/
public function setCategory(\Advert\Entity\Category $category = null)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return \Advert\Entity\Category
*/
public function getCategory()
{
return $this->category;
}
}
And my Category Entity:
namespace Advert\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Category
*
* #ORM\Table(name="category")
* #ORM\Entity
*/
class Category
{
/**
* #var integer
*
* #ORM\Column(name="category_id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $categoryId;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #ORM\ManyToMany(targetEntity="Advert", mappedBy="category")
**/
private $advertCategory;
public function __construct()
{
$this->advertCategory = new ArrayCollection();
}
/**
* Get categoryId
*
* #return integer
*/
public function getCategoryId()
{
return $this->categoryId;
}
/**
* Set name
*
* #param string $name
* #return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
Just as a first test, I have now tried the following in my Controller:
//Below Controller now works to echo the categories ArrayCollection
$data = $this->getEntityManager()->getRepository('Advert\Entity\Advert')->findAll();
foreach($data as $key=>$row)
{
echo $row->getAdvertTitle();
echo $row->getUser()->getUsername();
$categories = $row->getCategory();
foreach($categories as $row2) {
echo $row2->getName();
}
What am I doing wrong here? Can anyone give me an advice? Thank you very much in advance !
Honestly, and it's a very honest and fine thing, that this is way overcomplicating what you want to do, but only in specific areas.
If you used Composer to include Doctrine (the recommended way), also include symfony/console and you will get a whole mess of awesome tools to help you on your quest. There is a very specific command that will kick you in your seat for how awesome it is: $ doctrine orm:schema-tool:update --force --dump-sql. This will get Doctrine to run through your Entities (you only need the two) and will generate your tables and even setup the *To* associations for you. Int he case of ManyToOne's it will generate the appropriate Foreign Key schema. In the case of ManyToMany's it will automatically create, AND manage it's own association table, you just need only worry about giving the table a name in the Entity.
I'm not kidding you, Do this. It will make your life worth living.
As for your entity setup, this is all you need:
<?php
namespace Advert\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Advert
*
* #ORM\Table(name="advert")
* #ORM\Entity
*/
class Advert
{
/**
* #var integer
*
* #ORM\Column(name="advert_id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $advertId;
/**
* #var string
*
* #ORM\Column(name="advert_title", type="string", length=255, nullable=true)
*/
private $advertTitle;
/**
* #ORM\ManyToMany(targetEntity="Category", cascade={"persist"})
* #JoinTable(name="advert_categories")
*/
protected $category;
public function __construct()
{
$this->category = new ArrayCollection();
}
/**
* Get advertId
*
* #return integer
*/
public function getAdvertId()
{
return $this->advertId;
}
/**
* Set advertTitle
*
* #param string $advertTitle
* #return Advert
*/
public function setAdvertTitle($advertTitle)
{
$this->advertTitle = $advertTitle;
return $this;
}
/**
* Get advertTitle
*
* #return string
*/
public function getAdvertTitle()
{
return $this->advertTitle;
}
/**
* Set category
*
* #param ArrayCollection $category
* #return Advert
*/
public function setCategory(ArrayCollection $category)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return ArrayCollection
*/
public function getCategory()
{
return $this->category;
}
}
Notice that the getters and setters are Documented to Set and Return ArrayCollection, this is important for IDE's and tools that read PHPDoc and Annotations to understand how in-depth PHP class mapping works.
In addition, notice how much simpler the ManyToMany declaration is? The #JoinTable annotation is there to give a name to the table that doctrine will generate and manage. That's all you need!
But now, you probably should remove the $advertCategory property out of the Category Entity. Doctrine is going to auto-hydrate embedded Entities in properties with the Entity Association Mappings.
This is also potentially dangerous as it can result in infinite recursion. Basically, if all you requested was an Advert with ID of 1, it would go in and find ALL of the Category Entities associated to Advert 1, but inside of those Categories it's re-referencing Advert 1, which Doctrine will sub-query for and inject, which will contain a Category association, which will then Grab those categories, and so on and so fourth until PHP kills itself from lack of memory.
Once everything is good to go, and you got some Categories associated with your Advert, using the Getter for your category in the Advert entity will return an array of Category Entities. Simply iterate through them:
foreach($category as $advert->getCategories()) {
echo $category->getName();
}
or
echo current($advert->getCategories())->getName();
I'm usual working with symfony from the 2.1 or 2.2 versions.
Today i started a new project on the 2.3 and i'm encountering problems to create my custom entity repository.
My entity is:
<?php
namespace Acme\MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* AnnualProduction
*
* #ORM\Table(name="Annual_Production")
* #ORM\Entity(repositoryClass="Acme\MyBundle\Entity\AnnualproductionRepository")
*/
class AnnualProduction
{
/**
* #var string
*
* #ORM\Column(name="device_address", type="string", length=45, nullable=true)
*/
private $deviceAddress;
/**
* #var integer
*
* #ORM\Column(name="mese_1", type="integer", nullable=true)
*/
private $mese1;
/**
* #var integer
*
* #ORM\Column(name="mese_2", type="integer", nullable=true)
*/
SOME MISSING VAR SET AND GET
/**
* #var string
*
* #ORM\Column(name="sens_id", type="string", length=45)
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
private $sensId;
/**
* #var \DateTime
*
* #ORM\Column(name="AAAA", type="date")
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
private $aaaa;
/**
* Set deviceAddress
*
* #param string $deviceAddress
* #return AnnualProduction
*/
public function setDeviceAddress($deviceAddress)
{
$this->deviceAddress = $deviceAddress;
return $this;
}
/**
* Get deviceAddress
*
* #return string
*/
public function getDeviceAddress()
{
return $this->deviceAddress;
}
/**
* Set mese1
*
* #param integer $mese1
* #return AnnualProduction
*/
public function setMese1($mese1)
{
$this->mese1 = $mese1;
return $this;
}
/**
* Get mese1
*
* #return integer
*/
public function getMese1()
{
return $this->mese1;
}
/**
* Set sensId
*
* #param string $sensId
* #return AnnualProduction
*/
public function setSensId($sensId)
{
$this->sensId = $sensId;
return $this;
}
/**
* Get sensId
*
* #return string
*/
public function getSensId()
{
return $this->sensId;
}
/**
* Set aaaa
*
* #param \DateTime $aaaa
* #return AnnualProduction
*/
public function setAaaa($aaaa)
{
$this->aaaa = $aaaa;
return $this;
}
/**
* Get aaaa
*
* #return \DateTime
*/
public function getAaaa()
{
return $this->aaaa;
}
}
I dont write all variable and get and sets functions.
I've created a repository file: Acme\MyBundle\Entity\AnnualproductionRepository.php
The code for the repository file is the following:
<?php
namespace Acme\MyBundle\Entity;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
use Acme\MyBundle\Entity\AnnualProduction;
class AnnualproductionRepository extends EntityRepository
{
public function findByYearMonthDay($anno, $mese, $giorno, $sensId)
{
$query = $this->getEntityManager()
->createQuery(" SOME QUERY HERE")->setParameters(array(SOME PARAMETERS HERE));
return $query->getSingleResult();
}
}
I call the repository in one of my controller, with the following code:
<?php
namespace Acme\MyBundle\Controller;
use Acme\MyBundle\Entity\AnnualProduction;
use Acme\MyBundle\Entity;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Constraints\Date;
class DataController extends Controller{
public function indexUserAction(){
*
*
*
*
*
$DailyProduction=$DailyProduction+$em->getRepository('AcmeMyBundle:AnnualProduction')->findByYearMonthDay($year, $month, $day, $productionSensor);
*
*
*
*
}
}
But i get this error like the repository doesnt exist and the controller get the function name like a default findBy* on one of the Entity attributes.
ERROR:
*> Entity 'Acme\MyBundle\Entity\AnnualProduction' has no field
'yearMonthDay'. You can therefore not call 'findByYearMonthDay' on the
entities' repository***
Have you some advise to solve this problem? the code seems to be identical to the one i usualy add to include custom entity repository in symfony 2.2 but for some reason it refuse to work.
Tx for your time and Help.
Problem Solved, the fact was that the entity.orm.xml files, stored in /src/acme/myBundle/config/doctrine, have an hight priority over the entity files, so every modification to the entity that i was doing wasent readed.
SOLUTION: Delete all the entity.orm.xml files after done the annotation ed the generation of the entity via terminal php command.
The namespace for your repository is wrong. You should have Acme\MyBundle\Entity\Repository for a namespace instead. The path to your file ought to then be Acme/MyBundle/Entity/Repository/AnnualProduction.
You should also let doctrine generate all your entities for you via
php app/console doctrine:generate:entities Acme
You will then see a folder called Repositories in your Entities folder and thats where all the entities need to be stored.
I'm making entities with Symfony2 and Doctrine2. I made some entities that represent a many-to-many relation between two of my entities.
An example of one of these entities :
/**
* #ORM\Entity
*/
class Contact_Conference_Invitation
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Aurae\UserBundle\Entity\Contact")
*/
private $contact;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Aurae\ConferenceBundle\Entity\Conference")
*/
private $conference;
/**
* #var datetime dateInvitation
*
* #ORM\Column(name="dateInvitation", type="datetime")
*/
private $dateInvitation;
//Getters and setters
}
I have tried updating my sql schema, but the tables corresponding to these entities do not appear. Is there somewhere I have to declare them (config or such)? If not, what's wrong?
Thanks a lot
Edit : I had forgotten the namespace for these class, and that's why they were omitted by Doctrine. Another case closed :) thanks for the answers!
Assumptions ...
No, you don't need to declare them anywhere else than in your Entity directory.
What's the error message you got?
I guess you added
use Doctrine\ORM\Mapping as ORM;
on the top of your classes to let them be mapped.
I tried ...
I tried to generate your entities by adding a simple Contact & Conference entities and it's working fine.
Here are the code snippets:
Contact_Conference_Invitation.php
namespace Ahsio\StackBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Contact_Conference_Invitation
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Ahsio\StackBundle\Entity\Contact")
*/
private $contact;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Ahsio\StackBundle\Entity\Conference")
*/
private $conference;
/**
* #var datetime dateInvitation
*
* #ORM\Column(name="dateInvitation", type="datetime")
*/
private $dateInvitation;
//Getters and setters
}
Contact.php
namespace Ahsio\StackBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Contact
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #param $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Conference.php
namespace Ahsio\StackBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Conference
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #param $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Here are the generated tables:
NB: I used a specific namespace for the entities generation to work fine, you need to change them.
Also don't forget to check that you have automapping enabled.
In your config.yml you should have
doctrine:
orm:
auto_mapping: true
Came across this question because my entities weren't generated as well, this was my issue, it could save some time to people struggling with the same issue.
I don't see the definition of your ManyToMany relation in the sample of code you provided.
As an example, here's a ManyToMany relationship I implemented for a project
Entity Project.php
/**
* #var Provider[]
*
* #ORM\ManyToMany(targetEntity="Provider", mappedBy="projects")
*/
protected $providers = null;
Entity Provider.php
/**
* #var Project[]
*
* #ORM\ManyToMany(targetEntity="Project", inversedBy="providers")
* #ORM\JoinTable(name="PROVIDER_PROJECT")
*/
protected $projects = null;
As you can see, here you define the join table for your ManyToMany relationship.
Of course those entities are specific for my particular project but you get the idea and you can adapt it easily for your needs.
How can i create a relationship between entities with Symfony 2 and Doctrine? I'm only able to create standalone entities. Maybe someone can help me figure this out using the entity generator? I want to:
Create two entities: Post and Category. A Post is part of a Category.
Create a Tag entity: A Post can have many Tags.
A practical example is covered in Symfony2 docs here:
http://symfony.com/doc/current/book/doctrine.html#entity-relationships-associations
To elaborate, taking the first example, you need to create a OneToMany relationship between your Category object and your Post object:
Category.php:
<?php
namespace Your\CustomBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Table(name="category")
* #ORM\Entity()
*/
class Category
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="Post", mappedBy="category")
*/
public $posts;
/**
* Constructor
*/
public function __construct()
{
$this->posts = new ArrayCollection();
}
/**
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Post.php
<?php
namespace Your\CustomBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="post")
* #ORM\Entity()
*/
class Post
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="posts")
*/
public $category;
/**
* #return integer
*/
public function getId()
{
return $this->id;
}
}
This should get you started. I've just written this so there might be errors :s
I'm making properties $posts and $category public here for brevity; however you'd probably be advised to make these private and add setters/getters to your classes.
Also note that $posts is an array-like Doctrine ArrayObject class especially for arrgregating entities, with methods like $category->posts->add($post) etc.
For more detail look into association mapping in the Doctrine documentation. You'll probably need to set up a ManyToMany relationship between Posts and Tags.
Hope this helps :)
You don't create the relationships with the entity generator itself.
Once the entity classes themselves exist (created either with the entity generator or written by hand), you then edit them to add the relationships.
For example, with your Post having many Tags example
namespace Your\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Your\Bundle\Entity\Post
*
* #ORM\Table(name="post")
* #ORM\Entity
*/
class Post
{
/**
* #var \Doctrine\ORM\PersistentCollection
*
* #ORM\OneToMany(targetEntity="Tag", mappedBy="post", cascade={"persist"})
*/
private $tags;
}
See Doctrine's Documentation for more information about specifying relationships.