Hy,
I have problem with validation and schema creation
I am creating an api via the api platform, (this is my 1st project under symfony)
I have a constraint, the database exists and I cannot touch it.
I have an headerOrder entity and an LineOrder entity.
But the column of join are not a key.
class enteteCommande
{
/**
* #var int
*
* #ORM\Column(name="I_ID", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $IId;
/**
* #var string
*
* #ORM\Column(name="C_CDE_NUMERO", type="string", length=50, nullable=true)
*
*/
#[Groups(['write:commande'])]
private $CCdeNumero;
/**
*
* #ORM\ManyToMany(targetEntity="lignesCommande", mappedBy="enteteLigne")
*
*/
private $detailLigne;
class lignesCommande
{
/**
* #varint
*
* #ORM\Column(name="I_IDL", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $IIdL;
/**
* #varstring|null
*
* #ORM\Column(name="LIGNE_C_CDE_NUMERO", type="string", length=50, nullable=true)
*/
private $ligneCCdeNumero;
/**
*
*
* #ORM\ManyToMany(targetEntity="enteteCommande", inversedBy="detailLigne")
* #ORM\JoinColumn(name="LIGNE_C_CDE_NUMERO", referencedColumnName="C_CDE_NUMERO")
*
*/
private $enteteLigne;
My schema :
enteteCommande
I_ID
C_CDE_NUMERO
lignesCommande
I_IDL
LIGNE_C_CDE_NUMERO
And error log :
The referenced column name 'id' has to be a primary key column on the target entity class 'App\Entity\OrderLignes'.
The referenced column name 'id' has to be a primary key column on the target entity class 'App\Entity\OrderEntete'.
How to make manytomany without key ?
thank !
You need to configure the JoinTable on the owning side of the relationship (lignesCommande). Not just a JoinColumn. If the JoinTable configuration is missing, Doctrine will fall back to its default ManyToMany configuration and try to connect id primary key columns, which in your case won't work.
Here's an example (but untested) JoinTable annotation:
/**
* #ORM\ManyToMany(
* targetEntity="enteteCommande",
* inversedBy="detailLigne"
* )
* #ORM\JoinTable(
* name="foobar",
* joinColumns={
* #ORM\JoinColumn(
* name="LIGNE_C_CDE_NUMERO",
* referencedColumnName="LIGNE_C_CDE_NUMERO"
* ),
* },
* inverseJoinColumns={
* #ORM\JoinColumn(
* name="C_CDE_NUMERO",
* referencedColumnName="C_CDE_NUMERO"
* ),
* }
* )
*/
private $enteteLigne;
Related
Firstly sorry for my English)
I have following tables:
1) rejection_reasons
rejection_reason_id
locale_code
title
Primary key: rejection_reason_id, locale_code
2) order_rejection_reasons
order_id
rejection_reason_id
Primary key: order_id
Foreign key: rejection_reason_id (Note! without field locale_code)
Entities:
class RejectionReason
{
/**
* #var int
*
* #ORM\Id
* #ORM\Column(name="rejection_reason_id", type="smallint", length=1, nullable=false)
*/
private $id;
/**
* #var string
*
* #ORM\Id
* #ORM\Column(name="locale_code", type="string", length=2, nullable=false, options={"fixed"=true})
*/
private $localeCode;
/**
* #ORM\OneToMany(targetEntity="OrderRejectionReason", mappedBy="rejectionReason", cascade={"remove", "persist"}, orphanRemoval=true)
*/
private $orderRejectionReasons;
/**
* #param int $id
* #param string $localeCode
*/
public function __construct($id, $localeCode)
{
$this->id = $id;
$this->localeCode = $localeCode;
$this->orderRejectionReasons = new ArrayCollection();
}
}
class OrderRejectionReason
{
/**
* #var int
*
* #ORM\Column(name="order_id", type="integer", nullable=false, options={"unsigned"=true})
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var RejectionReason
*
* #ORM\ManyToOne(targetEntity="RejectionReason", inversedBy="orderRejectionReasons")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="rejection_reason_id", referencedColumnName="rejection_reason_id", nullable=false, onDelete="CASCADE")
* })
*/
private $rejectionReason;
}
Doctrine returns error:
The join columns of the association 'rejectionReason' have to match to ALL identifier columns of the target entity 'App\Entity\RejectionReason', however 'locale_code' are missing.
Could you help me set relation between these tables?
The join columns of the association 'rejectionReason' have to match to ALL identifier columns, so you should take a look at the identifier columns. As you can see localcode is marked as an id (#ORM\Id) aswell as id, this means that you created a composite primary key.
Take a look at: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/tutorials/composite-primary-keys.html
Because it is a composite primary key you cannot relate to only one of the two identifiers (JoinColumn, referencedColumnName="id").
You may consider making localeCode unique instead of an id which should solve you problem.(so you have to decide if localCode should be an id) You could also try to add localCode to the JoinColumn annotation.
Try without the extra curly braces and JoinColumn statement
class OrderRejectionReason
{
/**
* #var RejectionReason
*
* #ORM\ManyToOne(targetEntity="RejectionReason", inversedBy="orderRejectionReasons")
* #ORM\JoinColumn(name="rejection_reason_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
private $rejectionReason;
}
EDIT I:
Added name="rejection_reason_id", referencedColumnName="rejection_reason_id"
EDIT II:
Changed referencedColumnName="rejection_reason_id" to referencedColumnName="id"
I have entity Users and three unique fields and use for this #UniqueEntity, but I don't know how in message visible exactly fields already in DB ? I think maybe like Assert annotation
* #Assert\Type(
* type="array",
* message="The value {{ value }} is not a valid {{ type }}."
* )
but not work
my entity:
/**
* Users.
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="Artel\ProfileBundle\Entity\UsersRepository")
* #ExclusionPolicy("all")
* #UniqueEntity(
* fields={"email", "telephone", "skype"},
* errorPath="entity",
* message="This email, telephone or skype is already."
* )
*/
class Users implements UserInterface
{
use Timestampable;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, unique=true, nullable=true)
* #Expose()
* #Assert\Length(min=3, max=255)
* #Assert\NotBlank()
* #Assert\Email()
*/
protected $email;
/**
* #var string
*
* #ORM\Column(name="skype", type="string", length=255, unique=true, nullable=true)
* #Assert\Length(min=3, max=255)
* #Expose()
*/
protected $skype;
/**
* #var string
*
* #ORM\Column(name="telephone", type="string", length=255, unique=true, nullable=true)
* #Assert\Length(min=3, max=255)
* #Expose()
*/
protected $telephone;
You have configure the constraint with the unique of the tuple: combination value of the field email telephone and skype is unique.
From the doc:
This required option is the field (or list of fields) on which this
entity should be unique. For example, if you specified both the email
and name field in a single UniqueEntity constraint, then it would
enforce that the combination value is unique (e.g. two users could
have the same email, as long as they don't have the same name also).
If you need to require two fields to be individually unique (e.g. a unique email and a unique username), you use two UniqueEntity entries,
each with a single field.
So you need to specify three different unique constraint, as example:
/**
* Users.
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="Artel\ProfileBundle\Entity\UsersRepository")
* #ExclusionPolicy("all")
* #UniqueEntity(
* fields="email",
* errorPath="entity",
* message="This email is already in use."
* #UniqueEntity(
* fields="telephone",
* errorPath="entity",
* message="This telephone is already in use."
* #UniqueEntity(
* fields="skype",
* errorPath="entity",
* message="This skype account is already in use."
* )
*/
class Users implements UserInterface
Hope this help
hi i'm trying to link a class test with 2 entities, the Administrator that post the test and the competence (subject of the test ), but whatever i do i only get 1 index FK on my database after schema update
namespace Admin\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Test
*
* #ORM\Table(name="test")
* #ORM\Entity
*/
class Test
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="type", type="string", length=50, nullable=false)
*/
private $type;
/**
* #var integer
* #ORM\ManyToOne(targetEntity="ProjetCompetenceListe")
* #ORM\JoinColumn(name="id_competence", referencedColumnName="id")
*/
private $idCompetence;
/**
* #var \Administrateur
*
* #ORM\ManyToOne(targetEntity="Administrateur")
* #ORM\JoinColumn(name="id_administrateur", referencedColumnName="id")
*/
private $idAdministrateur;
please can any one tell me why ?
Have you tried creating indexes with #index annotation, maybe you should give it a try. Ref
add index with #index annotation and then run schema update command
You may need to clear doctrine meta data :
php app/console doctrine:cache:clear-metadata
Otherwise do a :
php app/console doctrine:schema:validate
to check if the relations are correct.
I have this Entity in Symfony2 :
<?php
namespace Project\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Users
*
* #ORM\Table(name="users")
* #ORM\Entity
*/
class Users
{
/**
* #var integer
*
* #ORM\Column(name="user_id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $userId;
/**
* #var integer
*
* #ORM\Column(name="test", type="integer", nullable=false)
*/
private $test;
}
I add the following line between {{userId}} and {{test}} :
/**
* #var integer
*
* #ORM\Column(name="superbanana", type="integer", nullable=false)
*/
private $superbanana;
Then I execute in console :
php app/console doctrine:schema:update --dump-sql
It give me the response :
ALTER TABLE users ADD superbanana INT NOT NULL
**How can I do to have instead ? **
ALTER TABLE users ADD superbanana INT NOT NULL AFTER user_id
If you don't want to drop/create the table, you can use #columnDefinition attribute and define the column definition yourself.
/**
* #var integer
*
* #ORM\Column(type="integer", columnDefinition="INT NOT NULL AFTER `user_id`")
*/
private $superbanana;
I don't think this is possible because using Doctrine means that you don't care about how the Table is managed anymore (apparently someone tried it before).
And since you never use MySQL directly, I think there is no utility to specify column orders for Doctrine.
But you can always delete your table so Doctrine will completely rebuild the table, respecting your order.
I work with Symfony2.0 and Doctrine, and I created this entity:
class MetaInformationsQuestionUser
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Myproject\Bundle\UserBundle\Entity\User")
*/
private $user;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Myproject\Bundle\QuestionsBundle\Entity\MetaInformationsQuestion")
*/
private $metainformationsquestion;
/**
* #var datetime $created
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $created;
/**
* #var datetime $updated
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(type="datetime")
*/
private $updated;
/**
* #var array $score
*
* #ORM\Column(name="score", type="array", nullable="true")
*/
private $score;
So this entity is a link for a many-to-many relation with attributes. (in this case, the score and creation and update dates).
My idea is to add a record of every question that each user plays, with the score he gets.
My problem is that I get this error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-3' for key 'PRIMARY'
So my question is: How can I add for example the create date to the primary key, or just remove the fact to have a primary key on this?
Ok I got it,
I needed to add:
* #ORM\Id
In my created field:
/**
* #var datetime $created
*
* #ORM\Id
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $created;
It made what I wanted!
Here are the documentation:
https://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#annref-id