i have a problem mapping entities in Doctrine 2 (with Symfony2). Symfony says that error is in Perfil entity, but the Doctrine section profiler says that the error is en Funcion entity.
This is the error (on the browser):
The column id must be mapped to a field in class
AppsManantiales\CommonBundle\Entity\Perfil since it is referenced by a
join column of another class.
But, in the profiler:
AppsManantiales\CommonBundle\Entity\Funcion: The referenced column
name 'id' has to be a primary key column on the target entity class
'AppsManantiales\CommonBundle\Entity\Funcion'. The referenced column
name 'id' has to be a primary key column on the target entity class
'AppsManantiales\CommonBundle\Entity\Perfil'.
This is the relation er:
The Perfil entity, basically is:
class Perfil implements RoleInterface{
/**
* #ORM\Id
* #ORM\Column(type="integer", length=10)
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $idperfil;
/**
* #ORM\ManyToMany(targetEntity="Funcion", mappedBy="perfiles")
* #ORM\JoinTable(name="perfil_funcion",
* joinColumns={#ORM\JoinColumn(name="perfil", referencedColumnName="idperfil")},
* inverseJoinColumns={#ORM\JoinColumn(name="funcion", referencedColumnName="idfuncion")}
* )
*/
protected $funciones;
// More code...
}
The Funcion entity basically is:
class Funcion {
/**
* #ORM\Id
* #ORM\Column(type="integer", length=11)
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $idfuncion;
/**
* #ORM\ManyToMany(targetEntity="Perfil", inversedBy="funciones")
*/
protected $perfiles;
// More code...
}
Any ideas ? Thanks !
I think by default Doctrine relies on the convention that all primary keys in entities are represented by an attribute called $id. Two solutions :
Rename your primary keys from $idperfil and $idfuncion to $id (which I recommend);
Explicit the join criterion on your Funcion object on the $perfiles property:
* #ORM\JoinTable(name="perfil_function"),
* joinColumns={#ORM\JoinColumn(name="funcion", referencedColumnName="idfuncion")},
* inverseJoinColumns={#ORM\JoinColumn(name="perfil", referencedColumnName="idperfil")}
* )
Related
I'm trying to setup an FK between 2 entities in my DB. The parent table has a ManyToOne relationship to a child table. I can not join these tables using a normal parent_id => id FK due to how the child table is populated by external processes (the parent never knows the primary ID of the child).
Doctrine accepts the entities as shown below but Mysql fails when trying to add the FK to the table with the following error.
ALTER TABLE parent_tbl ADD CONSTRAINT FK_1172A832F85E0677 FOREIGN KEY (username) REFERENCES child_tbl (username);
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`dmname`.`#sql-f16_d8acf`, CONSTRAINT `FK_1172A832F85E0677` FOREIGN KEY (`username`) REFERENCES `child_tbl` (`username`))
class Parent
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Child")
* #ORM\JoinColumn(name="username", referencedColumnName="username", nullable=false)
*/
protected $username;
// ...
}
class Child
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*
* #var integer
*/
protected $id;
/**
* #ORM\Column(type="string", unique=true)
*
* #var string
*/
protected $username;
// ....
}
From the Doctrine limitations and known issues :
It is not possible to use join columns pointing to non-primary keys.
Doctrine will think these are the primary keys and create lazy-loading proxies with the data, which can lead to unexpected results.
Doctrine can for performance reasons not validate the correctness of this settings at runtime but only through the Validate Schema command.
So, if you run the doctrine:schema:validate command, you should get something like :
[Mapping] FAIL - The entity-class Parent mapping is invalid:
* The referenced column name 'username' has to be a primary key column on the target entity class Child.
I hope you find a workaround to keep your logic intact using a primary key as join column.
I have the following entity:
/**
* SeriesAuthorRole
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Blog\Bundle\CoreBundle\Entity\SeriesAuthorRoleRepository")
*/
class SeriesAuthorRole extends AuthorRoleAbstract
{
/**
* #var Series
*
* #ORM\ManyToOne(targetEntity="Blog\Bundle\CoreBundle\Entity\Series", inversedBy="authors")
* #ORM\JoinColumn(name="series", referencedColumnName="id", nullable=false)
* #ORM\Id
*/
private $series;
/**
* #var Author
*
* #ORM\ManyToOne(targetEntity="Blog\Bundle\CoreBundle\Entity\Author")
* #ORM\JoinColumn(name="author", referencedColumnName="id", nullable=false)
* #ORM\Id
*/
protected $author;
/**
* #var Role
*
* #todo Must be nullable
*
* #ORM\ManyToOne(targetEntity="Blog\Bundle\CoreBundle\Entity\Role")
* #ORM\JoinColumn(name="role", referencedColumnName="id", nullable=true)
* #ORM\Id
*/
protected $role;
// ... Getters, setters
}
The idea behind it is quite simple: We have author, role and series entities. A series can have several authors with various roles. A same author can fulfill multiple roles in a series.
Sometimes, we don't know exactly what was the role of the author. In this case, the NULL value will be used for the role, the NULL value standing for "I don't know".
I was taught not to use NULL in foreign composite keys unless it has meaning. Well, it has meaning here, and I know that this could be implemented without Doctrine. However, for now, Symfony 2 throws that error:
Entity of type Blog\Bundle\CoreBundle\Entity\BandAuthorRole is missing an assigned ID for field 'role'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.
500 Internal Server Error - ORMException
So how can I authorize NULL values in foreign composite keys ? Is it possible at all with Doctrine ?
Your #JoinColumn annotation is correct with referencing to http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-joincolumn
However,
Every entity with a composite key cannot use an id generator other
than “ASSIGNED”. That means the ID fields have to have their values
set before you call EntityManager#persist($entity).
http://docs.doctrine-project.org/en/2.0.x/tutorials/composite-primary-keys.html#general-considerations
i'm pretty new to Symfony and Doctrine and i'm facing a problem trying to set Class Table Inheritance. I have a parent Entity, called "TeamActionTarget", and 2 children called "Player" and "Competition".
The model of my parent entity is the following :
// src/Van/TeamsBundle/Entity/TeamActionTarget.php
namespace Van\TeamsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Van\TeamsBundle\Entity\TeamActionTarget
*
* #ORM\Entity
* #ORM\Table(name="van_teams_actions_targets")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type_id", type="integer")
* #ORM\DiscriminatorMap( {"1" = "Competition", "2" = "Player"} )
*/
abstract class TeamActionTarget
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Doctrine2 generated me a parent table, with 2 fields, "id" and "type_id", and 2 children tables, with their own unique fields.
What I want to do now is to retrieve all children BY TYPE, from an integer value posted from a form.
So in a controller, I coded this :
$em->getRepository('VanTeamsBundle:TeamActionTarget')->findByTypeId($targetType);
But Symfony2 returns me an error :
Entity "Van\TeamsBundle\Entity\TeamActionTarget" has no field "typeId"
Which is true. The entity model doesn't contain this field, only the parent class does. So I tried to add this field in the entity model, but I get a error when trying to update the entity, saying there is a conflict between this field and the discriminator.
My question is pretty easy, How can I retrieve my children BY TYPE, posted from a form ?
When using single table inheritance, you have to use the repository of the child class directly:
$em->getRepository('VanTeamsBundle:Player')->findAll();
If you would like to retrieve the different child entities dependent on a form, you have to use the entity alias (e.g. VanTeamsBundle:Player) as the form field value and pass it to the getRepository() method. Another way of doing this is by performing a custom mapping between the form field value and the entity alias using data transformers.
I having a following issue, I need to make a relationship with two tables, but with no regular id, i need to use strings column. Something like this:
/**
* #ORM\Entity
* #ORM\Table(name="sigtap_tb_procedimento")
*/
class Procedimento
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="ExcecaoCompatibilidade", mappedBy="procedimento_restricao")
* #ORM\JoinColumn(name="co_procedimento_restricao", referencedColumnName="co_procedimento")
*/
private $restricoes;
}
And another Entity
/**
* #ORM\Entity
* #ORM\Table(name="sigtap_rl_excecao_compatibilidade")
*/
class ExcecaoCompatibilidade
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Procedimento", inversedBy="restricoes")
* #ORM\JoinColumn(name="co_procedimento_restricao", referencedColumnName="co_procedimento")
*/
private $procedimento_restricao;
}
co_procedimento_restricao and co_procedimento_restricao are string type, The relation does not working. How can i solve this issue?
Your relation needs to reference a primary key in the other table.
May be I misunderstood your question but cant you reference the id collumn the relationship like this:
/**
* #ORM\OneToMany(targetEntity="ExcecaoCompatibilidade", mappedBy="procedimento_restricao")
*/
private $restricoes;
/**
* #ORM\ManyToOne(targetEntity="Procedimento", inversedBy="restricoes")
* #ORM\JoinColumn(name="co_procedimento_restricao", referencedColumnName="id")
*/
private $procedimento_restricao;
Take a look here:
http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html
using one-to-many relations with doctrine
The side using #OneToMany is always the inverse side of a relation from doctrine's pov ( possibly not what you consider being the inverse side ) and never has a join-column definition.
Remove the #JoinColumn annotation from class Procedimento.
#OneToMany has to use mappedBy and #ManyToOne (the owning side) uses inversedBy.
The join-column (or join-table) definition has to be on the owning side together with #ManyToOne.
When using a join-column the name of this column (which will be added to the table of the owning side entity aka the side being "many") will be specified by name="column_name" and the referenced foreign key to store in there is the referencedColumnName="id"definition of the #JoinColum annotation.
I'm new with Symfony2 and Doctrine 2 ORM, then i got a problem with composite FK association.
While the association OneToMany-ManyToOne by a single auto-increment ID works good, i got many troubles with the same kind of association but through a composite PK.
What i would like to do is an entity-structure that mirrors the below shema.
http://imageshack.us/photo/my-images/9/z07m.jpg (Sorry but I cannot insert images into the post)
where
prd_product_data.product_id
prd_product_data.language_id
make up together the PK of 'prd_product_data'
and
prd_product_image.pdoduct_id
prd_product_image.language_id
make up the FK linked to the table 'prd_product_data'.
These below
prd_product_image.pdoduct_id
prd_product_image.language_id
prd_product_image.file_image_id
make up, all together, the PK of 'prd_product_image'.
I read that Doctrine 2.1 and up, supports natively the composed PK - FK association but there are very few examples. Moreover, surfing on the web, i found just scattered fragments of similar situations but nothing of useful.
The main issue now, is that i'm unable to create one unique object for the two ids, like such an unique id.
For example...
Snapshot for the Entity ProductData where "product and language should make up the same object:
/**
*
* #ORM\OneToMany(targetEntity="ProductImage", mappedBy="product")
*/
protected $products_Pimgs;
/**
*
* #ORM\OneToMany(targetEntity="ProductImage", mappedBy="language")
*/
protected $products_Limgs;
Snapshot for the Entity ProductImage where *product_id* and *language_id* made up the FK for the entity ProductData:
/**
*
* #ORM\Id
* #ORM\ManyToOne(targetEntity="ProductData", inversedBy="products_Pimgs")
* #ORM\JoinColumn(name="product_id", referencedColumnName="product_id")
*/
protected $product;
/**
*
* #ORM\Id
* #ORM\ManyToOne(targetEntity="ProductData", inversedBy="products_Limgs")
* #ORM\JoinColumn(name="language_id", referencedColumnName="language_id")
*/
protected $language;
/**
*
* #ORM\Id
* #ORM\ManyToOne(targetEntity="FileImage", inversedBy="files_images")
* #ORM\JoinColumn(name="file_image_id", referencedColumnName="id")
*/
protected $file_image;
From these snapshots it's evident that those keys are working separately.
In the end, this is my doctrine version, taken from the composer:
"doctrine/orm": ">=2.2.3,<2.4-dev",
How can i create an unique reference with two objects with ORM?
Read the documentation chapter Composite Primary Keys.
/**
* #ORM\Id
* #ORM\OneToMany(targetEntity="ProductImage", mappedBy="product")
*/
protected $products_Pimgs;
/**
* #ORM\Id
* #ORM\OneToMany(targetEntity="ProductImage", mappedBy="language")
*/
protected $products_Limgs;