Doctrine Many-To-Many - php

Tags Entity :
<?php
namespace App\Entity;
use App\Entity;
use Doctrine\ORM\Mapping;
/**
* #Entity
* #Table(name="tags", options={"collate":"utf8_general_ci", "charset":"utf8", "engine":"MyISAM"})
*/
class Tags extends Entity {
/**
* Many Tags have Many HolidayPackages.
* #ManyToMany(targetEntity="HolidayPackages", mappedBy="tags")
* #JoinTable(name="holiday_tags",
* joinColumns={#JoinColumn(name="tid", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="hpid", referencedColumnName="id")}
* )
*/
protected $holiday_packages;
/**
* #Column(type="string", length=255)
* #var string
*/
protected $tags;
/**
* #return mixed
*/
public function getHolidayPackages() {
return $this->holiday_packages;
}
/**
* #param mixed $holiday_packages
*/
public function setHolidayPackages($holiday_packages) {
$this->holiday_packages = $holiday_packages;
}
/**
* #return string
*/
public function getTags() {
return $this->tags;
}
/**
* #param string $tags
*/
public function setTags($tags) {
$this->tags = $tags;
}
}
Holiday Packages :
<?php
namespace App\Entity;
use App\Entity;
use Doctrine\ORM\Mapping;
/**
* #Entity
* #Table(name="holiday_packages", options={"collate":"utf8_general_ci", "charset":"utf8", "engine":"MyISAM"})
*/
class HolidayPackages extends Entity {
/**
* Many HolidayPackages have Many Tags.
* #ManyToMany(targetEntity="Tags", inversedBy="holiday_packages")
* #JoinTable(name="holiday_tags",
* joinColumns={#JoinColumn(name="hpid", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="tid", referencedColumnName="id")}
* )
*/
protected $tags;
/**
* #return mixed
*/
public function getTags() {
return $this->tags;
}
/**
* #param mixed $tags
*/
public function setTags($tags) {
$this->tags = $tags;
}
}
I am trying to create many-to-many assocation mapping. I follow this link :
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html to make this mapping.
But when i try to update doctrine, error occure :
[Doctrine\DBAL\DBALException]
An exception occurred while executing 'ALTER TABLE holiday_tags DROP PRIMARY KEY':
SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key
orm:schema-tool:update [--complete] [--dump-sql] [--force]
UPDATE
Entity Class :
<?php
namespace App;
use Doctrine\ORM\Mapping as ORM;
/**
* #MappedSuperclass
* #HasLifecycleCallbacks()
*/
abstract class Entity
{
/**
* #var integer
*
* #Column(name="id", type="integer")
* #Id
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Column(type="datetime")
* #var \DateTime
*/
protected $created_at;
/**
* #Column(type="datetime", nullable=true)
* #var \DateTime
*/
protected $updated_at;
/**
* Constructor
*/
public function __construct() {
$this->setCreatedAt(new \DateTime());
$this->setUpdatedAt(new \DateTime());
}
/**
* #PreUpdate
*/
public function setUpdatedValue() {
$this->setUpdatedAt(new \DateTime());
}
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* #param $created_at
*/
public function setCreatedAt($created_at) {
$this->created_at = $created_at;
}
/**
* #return \DateTime
*/
public function getCreatedAt() {
return $this->created_at->format('d/m/Y H:i');
}
/**
* #param $updated_at
*/
public function setUpdatedAt($updated_at) {
$this->updated_at = $updated_at;
}
/**
* #return \DateTime
*/
public function getUpdatedAt() {
return $this->updated_at;
}
}
It creates a class holidaypackages_tags but still give error and i specified name as holiday_tags but it named holidaypackages_tags...

You are trying to create the same table twice "holiday_tags"!
Try this:
class Tags extends Entity {
/**
* Many Tags have Many HolidayPackages.
* #ManyToMany(targetEntity="HolidayPackages", mappedBy="tags")
*/
protected $holiday_packages;
//...
}
class HolidayPackages extends Entity {
/**
* Many HolidayPackages have Many Tags.
* #ManyToMany(targetEntity="Tags", inversedBy="holiday_packages")
* #JoinTable(name="holiday_tags",
* joinColumns={#JoinColumn(name="hpid", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="tid", referencedColumnName="id")}
* )
*/
protected $tags;
//...
}
Notice that there is no annotation to create the same table again on $holiday_packages field

Related

Symfony3 "SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'catId' cannot be null "

I'm trying to save data with ManyToOne relations in a DataFixtures class. And I get this error on saving data.
Please, help me.
Sources:
Entity/DealsCategory.php:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* DealsCategory
*
* #ORM\Table(name="deals_category")
* #ORM\Entity(repositoryClass="AppBundle\Repository\DealsCategoryRepository")
*/
class DealsCategory
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="alias", type="string", length=50, nullable=true)
*/
private $alias;
/**
* #ORM\OneToMany(targetEntity="DealsCategoryLang", mappedBy="category")
*/
protected $categoryLang;
/**
* #return mixed
*/
public function getCategoryLang()
{
return $this->categoryLang;
}
/**
* #param DealsCategoryLang $categoryLang
*/
public function setCategoryLang(DealsCategoryLang $categoryLang = null)
{
$this->categoryLang = $categoryLang;
}
/**
* #param DealsCategoryLang $categoryLang
*/
public function setOneCategoryLang(DealsCategoryLang $categoryLang)
{
$this->categoryLang[] = $categoryLang;
}
/**
* DealsCategory constructor.
*/
public function __construct()
{
$this->categoryLang = new ArrayCollection();
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set alias
*
* #param string $alias
*
* #return DealsCategory
*/
public function setAlias($alias)
{
$this->alias = $alias;
return $this;
}
/**
* Get alias
*
* #return string
*/
public function getAlias()
{
return $this->alias;
}
}
Entity/DealsCategoryLang.php:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* DealsCategoryLang
*
* #ORM\Table(name="deals_category_lang")
* #ORM\Entity(repositoryClass="AppBundle\Repository\DealsCategoryLangRepository")
*/
class DealsCategoryLang
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="catId", type="integer")
*/
private $catId;
/**
* #var string
*
* #ORM\Column(name="lang", type="string", length=10)
*/
private $lang;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=70)
*/
private $title;
/**
* #ORM\ManyToOne(targetEntity="DealsCategory", inversedBy="categoryLang", cascade={"persist"})
* #ORM\JoinColumn(name="catId", referencedColumnName="id")
*
*/
protected $category;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set catId
*
* #param integer $catId
*
* #return DealsCategoryLang
*/
// public function setCatId($catId)
// {
// $this->catId = $catId;
//
// return $this;
// }
/**
* Get catId
*
* #return int
*/
public function getCatId()
{
return $this->catId;
}
/**
* Set lang
*
* #param string $lang
*
* #return DealsCategoryLang
*/
public function setLang($lang)
{
$this->lang = $lang;
return $this;
}
/**
* Get lang
*
* #return string
*/
public function getLang()
{
return $this->lang;
}
/**
* Set title
*
* #param string $title
*
* #return DealsCategoryLang
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
}
DataFixtures/ORM/LoadCategories.php
<?php
namespace AppBundle\DataFixtures\ORM;
use AppBundle\Entity\DealsCategory;
use AppBundle\Entity\DealsCategoryLang;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class LoadCategories implements FixtureInterface, ContainerAwareInterface
{
private $container;
/**
* Load data fixtures with the passed EntityManager
*
* #param ObjectManager $manager
*/
public function load(ObjectManager $manager)
{
$category = new DealsCategory();
$categoryLang = new DealsCategoryLang();
$categoryLang->setLang('en');
$categoryLang->setTitle('Food and Drinks');
$category->setOneCategoryLang($categoryLang);
$manager->persist($category);
$manager->persist($categoryLang);
$manager->flush();
}
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
}
I've tried it in different ways, but it's still not working. Tell me please, what i am doing wrong?
UPD:
my errors are:
[Doctrine\DBAL\Exception\NotNullConstraintViolationException]
An exception occurred while executing 'INSERT INTO deals_category_lang (catId, lang, title) VALUES (?, ?, ?)' with params [null, "en", "Food and Drinks"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'catId' cannot be null
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'catId' cannot be null
PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'catId' cannot be null
I am running the fixtures through the command line:
php bin/console doctrine:fixtures:load --append
Ok, I resolved it...
The problem was in my Fixture class:
Instead of
$category->setOneCategoryLang($categoryLang);
I should put the
$categoryLang->setCategory($category);
,respecting the hierarchy of my entities' relations :(

Symfony 2 Entity Repository find() returns empty array

Thank you all for your answers from now. ThatÅ› the question. I have a symfony 2 app with two entities (Tasks and Products). When i tried to find (findBy,findOneBy,findAll) a product it returns an empty array.
Tasks Entity
<?php
namespace pablo\UserBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Task
*
* #ORM\Table(name="tasks")
* #ORM\Entity(repositoryClass="pablo\UserBundle\Repository\TaskRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Task
{
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="tasks")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $user;
/**
* #ORM\ManyToOne(targetEntity="Product", inversedBy="task")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $product;
public function __construct()
{
$this->tasks = new ArrayCollection();
}
/**
* Set product
*
* #param \pablo\UserBundle\Entity\Product $product
*
* #return Task
*/
public function setProduct(\pablo\UserBundle\Entity\Product $product = null)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* #return \pablo\UserBundle\Entity\Product
*/
public function getProduct()
{
return $this->product;
}
/**
* #return ArrayCollection
*/
public function getTasks()
{
return $this->tasks;
}
/**
* #param ArrayCollection $tasks
*/
public function setTasks($tasks)
{
$this->tasks = $tasks;
}
And Products Entity
<?php
namespace pablo\UserBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* Products
*
* #ORM\Table(name="products")
* #ORM\Entity(repositoryClass="pablo\UserBundle\Repository\ProductsRepository")
* #UniqueEntity("productsName")
*/
class Product
{
/**
* #ORM\OneToMany(targetEntity="Task", mappedBy="product")
*/
protected $task;
/**
* #ORM\OneToMany(targetEntity="Publicaciones", mappedBy="product")
*/
protected $publicaciones;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="products_name", type="string", length=255)
* #Assert\NotBlank()
*/
private $productsName;
public function __construct()
{
$this->task = new ArrayCollection();
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set productsName
*
* #param string $productsName
*
* #return Product
*/
public function setProductsName($productsName)
{
$this->productsName = $productsName;
return $this;
}
/**
* Get productsName
*
* #return string
*/
public function getProductsName()
{
return $this->productsName;
}
public function __toString() {
return $this->productsName;
}
/**
* Get task
*
* #return \Doctrine\Common\Collections\ArrayCollection
*/
public function getTask()
{
return $this->task;
}
/**
* Set task
*
* #param \Doctrine\Common\Collections\ArrayCollection $typeSponsor
*
* #return Task
*/
public function setTask($task)
{
$this->task = $task;
}
/**
* #return mixed
*/
public function getPublicaciones()
{
return $this->publicaciones;
}
/**
* #param mixed $publicaciones
*/
public function setPublicaciones($publicaciones)
{
$this->publicaciones = $publicaciones;
}
}
Now, when i tried to find a product from controller it returns an empty array ({}). I can't see what is wrong with this.
$productId = '18';
$product = $this->get('doctrine.orm.default_entity_manager')->getRepository('pabloUserBundle:Product')->find($productId);
Actually you have a result, it just is an empty object because you have not defined which of the properties should be printed.
The best solution is for your entity to implement JsonSerializable.
class Product implements \JsonSerializable
{
...
public function jsonSerialize()
{
return [
"id"=> $this->getId(),
"name" => $this->getProductsName()
];
}
Now it knows what it should print when converting the class to json object.
If you want the task collection also, implement JsonSerializable for the Task Entity and add in Product Entity:
public function jsonSerialize()
{
return [
"id"=> $this->getId(),
"name" => $this->getProductsName(),
"task" => $this->getTask()->toArray()
];
}
The JsonSerializable interface

Embedded forms relations doctrine

in my symfony app, i'm using embedded forms. In my case, an object "CompetenceGroupe" can have multiple objects "CompetenceItem", but an object "CompetenceItem" belongs to only one object "CompetenceGroupe", so the relation is manyToOne.
The form work perfectly, and I have two tables (one for each entity), and it's well saved in the database.
But when I select an CompetenceGroupe object with doctrine in my controller, I have all informations of the object, and he's got an empty "competenceItems" property, so I can't retrieve the childs object (CompetenceItem).
My "CompetenceGroupe" entity :
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="competences_groupes")
*/
class CompetenceGroupe
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id_competence_groupe;
/**
* #var User $user
*
* #ORM\ManyToOne(targetEntity="User", cascade={"persist", "merge"})
* #ORM\JoinColumn(name="id_user", referencedColumnName="id_user", nullable=false)
*/
private $user;
/**
* #ORM\Column(type="string", length=60, nullable=true)
*/
protected $titre;
protected $competence_items;
public function __construct()
{
$this->competence_items = new ArrayCollection();
}
public function getCompetenceItems()
{
return $this->competence_items;
}
/**
* Get idCompetenceGroupe
*
* #return integer
*/
public function getIdCompetenceGroupe()
{
return $this->id_competence_groupe;
}
/**
* Set titre
*
* #param string $titre
*
* #return CompetenceGroupe
*/
public function setTitre($titre)
{
$this->titre = $titre;
return $this;
}
/**
* Get titre
*
* #return string
*/
public function getTitre()
{
return $this->titre;
}
/**
* Set user
*
* #param \AppBundle\Entity\User $user
*
* #return CompetenceGroupe
*/
public function setUser(\AppBundle\Entity\User $user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
public function addItem(CompetenceItem $item)
{
$this->competence_items->add($item);
}
public function removeItem(CompetenceItem $item)
{
// ...
}
/**
* Set competenceItems
*
* #param \AppBundle\Entity\CompetenceItem $competenceItems
*
* #return CompetenceGroupe
*/
public function setCompetenceItems(\AppBundle\Entity\CompetenceItem $competenceItems = null)
{
$this->competence_items = $competenceItems;
return $this;
}
}
And my "CompetenceItem" entity :
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="competences_items")
*/
class CompetenceItem
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id_competence_item;
/**
* #ORM\Column(type="string", length=60, nullable=false)
*/
protected $libelle;
/**
* #var CompetenceNiveau $niveau
*
* #ORM\ManyToOne(targetEntity="CompetenceNiveau", cascade={"persist", "merge"})
* #ORM\JoinColumn(name="id_competence_niveau", referencedColumnName="id_competence_niveau", nullable=true)
*/
private $niveau;
/**
* #var CompetenceGroupe $competence_groupe
*
* #ORM\ManyToOne(targetEntity="CompetenceGroupe", cascade={"persist", "merge"})
* #ORM\JoinColumn(name="id_competence_groupe", referencedColumnName="id_competence_groupe", nullable=false)
*/
private $competence_groupe;
/**
* Get idCompetenceItem
*
* #return integer
*/
public function getIdCompetenceItem()
{
return $this->id_competence_item;
}
/**
* Set libelle
*
* #param string $libelle
*
* #return CompetenceItem
*/
public function setLibelle($libelle)
{
$this->libelle = $libelle;
return $this;
}
/**
* Get libelle
*
* #return string
*/
public function getLibelle()
{
return $this->libelle;
}
/**
* Set niveau
*
* #param \AppBundle\Entity\CompetenceNiveau $niveau
*
* #return CompetenceItem
*/
public function setNiveau(\AppBundle\Entity\CompetenceNiveau $niveau = null)
{
$this->niveau = $niveau;
return $this;
}
/**
* Get niveau
*
* #return \AppBundle\Entity\CompetenceNiveau
*/
public function getNiveau()
{
return $this->niveau;
}
/**
* Set competenceGroupe
*
* #param \AppBundle\Entity\CompetenceGroupe $competenceGroupe
*
* #return CompetenceItem
*/
public function setCompetenceGroupe(\AppBundle\Entity\CompetenceGroupe $competenceGroupe)
{
$this->competence_groupe = $competenceGroupe;
return $this;
}
/**
* Get competenceGroupe
*
* #return \AppBundle\Entity\CompetenceGroupe
*/
public function getCompetenceGroupe()
{
return $this->competence_groupe;
}
}
I think I have a missing annotation of the "competence_items" property in the CompetenceGroupe entity, but i'm really not sure ...
Thanks for your help !
A good practice may be to have a competence form, which would be call inside your competence group form
You may add a CollectionType as parrent and include query to search which competence already exist
There are some good example with post form type in symfony demo blog
Or you can use form events (onSubmit, preSubmit, etc...) to charge your entity with your required competence. This example show a message form which allow to choose friend from preset data, this is a good example.
You have tow choice , even to create a Many-To-One, Unidirectional , in this case , you need clean some code , take a look:
In CompetenceGroupe class :
class CompetenceGroupe
{
/**
* Many competence have One Group.
* #ManyToOne(targetEntity="CompetenceItem")
* #JoinColumn(name="id_competence_item", referencedColumnName="id_competence_item")
*/
protected $competence_items;
public function __construct()
{
// $this->competence_items = new ArrayCollection();
//delete that line
}
In CompetenceItem class :
class CompetenceItem
{
You need to delete private $competence_groupe; attribute with his annotation :
By this way, when you dump a CompetenceGroupe object you gonna find the competence items.
Also, you can do it with One-To-Many, Bidirectional ,if you want to get the data from the inverse side and from the owning side .
EDIT: If one competenceGroupe can have many competenceItems, then that is a OneToMany relationship; this is the inverse side of the relationship as defined by doctrine, but that is ok. Your question asked how to pull a competenceGroupe and retrieve all related competenceItems. You can do this by making the competenceItems an ArrayCollection in your CompetenceGroupe entity, just as you have done. You do have to define that further in the annotation, see (updated) code below.
For an ArrayCollection, you can remove your method setCompetenceItems and instead define a method addCompetenceItem in your CompetenceGroupe entity.
class CompetenceGroupe
{
/**
* #ORM\OneToMany(targetEntity="CompetenceItem", mappedBy="competence_groupe")
*/
protected $competenceItems;
public function __construct()
{
$this->competenceItems= new ArrayCollection();
}
/**
* Add competenceItem
*
* #param CompetenceItem $competenceItem
* #return CompetenceGroupe
*/
public function addCompetenceItem(CompetenceItem $competenceItem)
{
$this->competence_items->add($competenceItem);
return $this;
}
}
You'll also need to define the owning side to make all this work.

Foreign key on composite primary key not working

I have an entity that references another entity with a composite primary key.
I'm simply doing a ManyToOne relationship. Each company can have many trades. Each company is part of some Stock Exchange and its unique identifier is both the Stock Exchange they're listed on and their stock symbol.
The error that I get when I try to update the schema is:
Column name ``id`` referenced for relation from Application\Entity\Trade towards Application\Entity\Company does not exist.
I think it's trying to default to id on the company. Is there any way to specify multiple foreign keys for the primary key on one table?
<?php
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="trade")
*/
class Trade
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="id",type="integer")
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $price;
/**
* #ORM\Column(type="integer")
*/
protected $size;
/**
* #ORM\Column(type="datetime")
*/
protected $dateTime;
/**
* #ORM\ManyToOne(targetEntity="Application\Entity\Company", inversedBy="trade")
*/
protected $company;
/**
* #return mixed
*/
public function getPrice()
{
return $this->price;
}
/**
* #param mixed $price
*/
public function setPrice($price)
{
$this->price = $price;
}
/**
* #return mixed
*/
public function getSize()
{
return $this->size;
}
/**
* #param mixed $size
*/
public function setSize($size)
{
$this->size = $size;
}
/**
* #return mixed
*/
public function getDateTime()
{
return $this->dateTime;
}
/**
* #param mixed $dateTime
*/
public function setDateTime($dateTime)
{
$this->dateTime = $dateTime;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return mixed
*/
public function getCompany()
{
return $this->company;
}
/**
* #param mixed $company
*/
public function setCompany($company)
{
$this->company = $company;
}
}
Here's the company entity if that helps
<?php
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="company")
*/
class Company
{
/**
* #ORM\Id
* #ORM\Column(length=5)
*/
protected $symbol;
/**
* #ORM\Id #ORM\ManyToOne(targetEntity="\Application\Entity\Exchange", inversedBy="company")
* #ORM\JoinColumn(name="exchangeKey", referencedColumnName="exchangeKey")
*/
protected $exchange;
/**
* #return mixed
*/
public function getSymbol()
{
return $this->symbol;
}
/**
* #param mixed $symbol
*/
public function setSymbol($symbol)
{
$this->symbol = $symbol;
}
/**
* #return mixed
*/
public function getExchange()
{
return $this->exchange;
}
/**
* #param mixed $exchange
*/
public function setExchange($exchange)
{
$this->exchange = $exchange;
}
}
You should be able to reference multiple columns using the #ORM\JoinColumns annotation. Inside you can define one or more #ORM\JoinColumn annotations.
For example
/**
* #ORM\ManyToOne(targetEntity="Application\Entity\Company", inversedBy="trade")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="symbol", referencedColumnName="symbol"),
* #ORM\JoinColumn(name="exchange", referencedColumnName="exchangeKey")
* });
*/
protected $company;
I was going to link to the documentation, however all I can find is this.
An array of #JoinColumn annotations for a #ManyToOne or #OneToOne relation with an entity that has multiple identifiers.

Symfony 3 Doctrine Composite Key: single id is not allowed on composite primary key in entity

I have an entity with an
integer column (compositeId)
and a
string column (asin)
I want both columns working as a composite key.
So I look here in the documentation:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html
But when I try to load my repository
$myEntity = $em->getRepository(MyEntity::class);
I got this error message:
single id is not allowed on composite primary key in entity
AppBundle\Entity\MyEntity
This is my Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #Entity(repositoryClass="AppBundle\Repository\MyEntityRepository")
* #Table(name="my_entity")
*/
class MyEntity {
/**
* #Column(type="integer")
* #GeneratedValue()
*/
protected $id;
/**
* #var integer
* #Id
* #Column(type="integer", name="composite_id")
*/
protected $compositeId;
/**
* #var string
* #Id
* #Column(type="string", name="asin")
*/
protected $asin;
/**
* #var string
* #Column(type="string", name="sku")
*/
protected $sku;
/**
* #var string
* #Column(type="string", name="ean")
*/
protected $ean;
/**
* #codeCoverageIgnore
* #return mixed
*/
public function getId() {
return $this->id;
}
/**
* #param mixed $id
*
* #return MyEntity;
*/
public function setId($id) {
$this->id = $id;
return $this;
}
/**
* #codeCoverageIgnore
* #return int
*/
public function getCompositeId() {
return $this->compositeId;
}
/**
* #param int $compositeId
*
* #return MyEntity;
*/
public function setCompositeId($compositeId) {
$this->compositeId = $compositeId;
return $this;
}
/**
* #codeCoverageIgnore
* #return string
*/
public function getAsin() {
return $this->asin;
}
/**
* #param string $asin
*
* #return MyEntity;
*/
public function setAsin($asin) {
$this->asin = $asin;
return $this;
}
/**
* #codeCoverageIgnore
* #return string
*/
public function getSku() {
return $this->sku;
}
/**
* #param string $sku
*
* #return MyEntity;
*/
public function setSku($sku) {
$this->sku = $sku;
return $this;
}
/**
* #codeCoverageIgnore
* #return string
*/
public function getEan() {
return $this->ean;
}
/**
* #param string $ean
*
* #return MyEntity;
*/
public function setEan($ean) {
$this->ean = $ean;
return $this;
}
}
What am I doing wrong?
When I remove #generatedValue at my ID table it works.
But I need auto generated values at my ID column.
I don't have any #Id annotation at my ID column, only #generatedValue, and on my both #Id columns I don't have any annotation with #generatedValue but I got this error ...
Doctrine only supports #GeneratedValue() on #Id fields.
This annotation is optional and only has meaning when used in conjunction with #Id.
https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref_generatedvalue
You may be able to use columnDefinition as a workaround, e.g.
#ORM\Column(type="integer", name="id", columnDefinition="INT AUTO_INCREMENT")
as suggested here: https://stackoverflow.com/a/34749619/380054
You need to remove all #Id in properties description except protected $id.

Categories