doctrine:schema:update doesn't respect column order - php

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.

Related

Doctrine - The referenced column name 'id' has to be a primary key

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;

Symfony 2 Doctrine persist Entity with related entities

I have a problem trying to persist a new entity with Symfony 2.7.11 that have a related Entity.
I need to create a Landing that can have many universities so I created 3 tables
landing
landingId (primary Key)
university
universityId (primary Key)
landingUniversity
landingId (both are primary Key) (foreign Key Landing)
universityId (foreign Key University)
And I have just 2 Entities (Landing & University) and a Many To Many relation (unidirectional, because I just want to know the universities added to a landing, so University hasn't got anything about landing)
First, I find each University on my database and I save them. Then I create the new Landing and I add all of them.
$universityRepository = $this->em->getRepository('University');
$universities = array();
foreach ($listUniversities as $universityId){
$university= $cursosRepository->findById($universityId);
$universities[] = $university[0];
}
$newLanding = new Landing();
$newLanding->setName($landing["name"]);
foreach ($universities as $university){
$newLanding->addUniversity($university);
}
$em = $this->getEntityManager();
$em->persist($newLanding);
$em->flush();
And I'm getting this error when symfony executes flush():
Could not resolve type of column "landingId" of class University
What I'm doing wrong?
My Entity:
/**
* Landing
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="LandingRepository")
*/
class Landing
{
/**
* #var integer
*
* #ORM\Column(name="landingid", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=250)
*/
private $name;
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="Language")
* #ORM\JoinColumn(name="languageId", referencedColumnName="languageId")
*/
private $languageId;
/**
* #ORM\ManyToMany(targetEntity="University")
* #ORM\JoinTable(name="landingUniversity",
* joinColumns={#ORM\JoinColumn(name="landingId", referencedColumnName="landingId")},
* inverseJoinColumns={#ORM\JoinColumn(name="unversityId", referencedColumnName="unversityId")}
* )
*/
private $universities;
Thank you so much!!!
The error message is really explicit. Your error is here :
joinColumns={#ORM\JoinColumn(name="landingId", referencedColumnName="landingId")}
should be
joinColumns={#ORM\JoinColumn(name="landingId", referencedColumnName="landingid")}
because your Landing entity doesn't contain any landingId database field, but landingid.
But you'd rather edit the column name of your $id property :
/**
* #var integer
*
* #ORM\Column(name="landingId", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

Symfony2 ORM schema update with 2 FK

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.

Symfony2 Docrtine - Every Entity must have an identifier/primary key - It does have a primary key?

Having a strange issue with SF2 and Doctrine. When trying to run my app from app.php I get this:
[2013-01-31 15:40:05] request.CRITICAL: Doctrine\ORM\Mapping\MappingException: No identifier/primary key specified for Entity 'ACME\MyBundle\Entity\MyEntity'. Every Entity must have an identifier/primary key. (uncaught exception) at /lib/Doctrine/ORM/Mapping/MappingException.php line 37 [] []
Which seems fairly self explanatory. But as far as I can see , I have a Primary key on my entity:
My Entity:
/**
* #ORM\Entity
* #ORM\Table(name="milestone")
*/
class MyEntity
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string")
* #Assert\NotBlank()
* #Assert\MinLength(2)
* #Assert\MaxLength(100)
*/
protected $title;
/**
* #ORM\Column(type="datetime")
* #Assert\NotBlank()
*/
protected $date;
//////ETC
And then in PHPMyAdmin:
Action Keyname Type Unique Packed Column Cardinality Collation Null Comment
Edit Drop PRIMARY BTREE Yes No id 63 A
I have the primary key. Non are NULL.
Running using app_dev.php the app runs fine, I'm assuming as the error is suppressed.
try using this. It is working for me
/**
* #var integer $id
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
I would suggest setting the field to be not nullable.
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
In any case since you have the table, you can always generate your entity map using doctrine's cli which is very convenient.
php [path-to-doctrine]/doctrine orm:convert-mapping --filter="TableNameInCamelCase" --namespace="[your-entity-namespace]" --force --from-database annotation [destination-path-of-entities]
There's even one for generating the getters and setters.

Doctrine #UniqueEntity with ManyToOne fields?

I'm trying to create a UniqueEntity with 2 fields (both are ManyToOne fields).
The code is as follow:
/*
* #ORM\Table()
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
* #UniqueEntity(fields={"user", "connect"})
*/
class UserConnect
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var boolean $isLeader
*
* #ORM\Column(name="isLeader", type="boolean")
*/
private $isLeader;
/**
* #var date $joinedDate
*
* #ORM\Column(name="joinedDate", type="date")
*/
private $joinedDate;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="userConnects")
*
*/
private $user;
/**
* #ORM\ManyToOne(targetEntity="Connect", inversedBy="userConnects")
*
*/
private $connect;
The goal is to ensure that I've got only one Entity that link a USER with a CONNECT.
Should I write something else in my #UniqueEntity declaration?
I understand you want to get an error only when both user and connect fields for one record are duplicated in other record in the database.
The #UniqueEntity annotation is rightly declared for your purpose (multiple column index) but only will be triggered in the form validation and doesn't affects the DDBB schema.
If you want to add the same check at database level you should use the #UniqueConstraint annotation in the Table() declaration and give a name to the new index. Something like:
/*
* #ORM\Table(uniqueConstraints={#ORM\UniqueConstraint(name="IDX_USER_CONNECT", columns={"user_id", "connect_id"})})
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
* #UniqueEntity(fields={"user", "connect"})
*/
class UserConnect
{
In the other hand, if you declare #ORM\Column(unique=true) in each attribute you will get a very different behavior, it won't be a multiple column index but you will have two independent unique columns, if you enter twice the same user_id you will get an error independently of the connect_id value, and the same will happens if you enter twice the same connect_id value.
This works:
/**
* State
*
* #ORM\Table(
* name="general.states",
* uniqueConstraints={
* #ORM\UniqueConstraint(name="states_country_name_code_key", columns={"idcountry", "name","code"}),
* })
* #ORM\Entity(repositoryClass="Fluency\Bundle\GeneralBundle\Entity\Repository\StateRepository")
*/
class State
{.......
Taken from an entity on my system. This way affects Database schema. See where i put #\ORM\UniqueConstraint annotation. Sorry #estopero... next time i must read first the other answers.
you should add the unique declaration in your attributes annotations too.
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="userConnects")
* #ORM\Column(unique=true)
*/
private $user;
/**
* #ORM\ManyToOne(targetEntity="Connect", inversedBy="userConnects")
* #ORM\Column(unique=true)
*/
private $connect;
See this symfony doc and this StackOverflow answer.

Categories