Semantical Error - Couldn't find constant X, class... ERROR - php

I am trying to implement category and subcategory structure entity, but I end up with this error when generating entity with command php app/console generate:doctrine:entities RFQIronilBundle:
[Doctrine\Common\Annotations\AnnotationException]
[Semantical Error] Couldn't find constant production, class RFQ\IronilBundl
e\Entity\ProductionType.
My created ProductionType entity:
<?php
namespace RFQ\IronilBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ProductionType
*
* #ORM\Table(production-type)
* #ORM\Entity
*/
class ProductionType
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=100)
*/
protected $name;
/**
* #ORM\OneToMany(targetEntity="ProductionType", mappedBy="parent")
**/
protected $children;
/**
* #ORM\ManyToOne(targetEntity="ProductionType", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id")
**/
protected $parent;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
How to generate my entity and what could causes this error?
Thank you!

I think it's because you aren't using speech marks around your table name.
#ORM\Table(production-type) // meant (constant) production minus (constant) type
where as you should use
#ORM\Table("production-type")
And it may make more sense to use production_type to stop the need to quotation marks around the table name in MySQL statements.

Related

Unrecognized id Field with Symfony 3 and FOSUserBundle

I keep getting the error in the title when I want to login using the FOSUserBundle on Symfony. The problem is, I already have an "id" for my User table from my database so I don't want to create an "id" field like they ask on the FOSUserBundle guide. I don't understand why it would give me this error when there is no more "id" field in my code.
Is this "id" field mandatory?
Here is the code of my User class (here called "Utilisateurs")`use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
/**
* Utilisateurs
*
* #ORM\Table(name="utilisateurs", indexes={#ORM\Index(name="FK_UTILISATEURS_id_sexe", columns={"id_sexe"}), #ORM\Index(name="FK_UTILISATEURS_id_niveau", columns={"id_niveau"})})
* #ORM\Entity
*/
class Utilisateurs extends BaseUser
{
public function __construct()
{
parent::__construct();
}
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=25, nullable=true)
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="prenom", type="string", length=25, nullable=true)
*/
private $prenom;
/**
* #var \DateTime
*
* #ORM\Column(name="date_naissance", type="date", nullable=true)
*/
private $dateNaissance;
/**
* #var string
*
* #ORM\Column(name="url_photo", type="string", length=100, nullable=true)
*/
private $urlPhoto;
/**
* #var integer
*
* #ORM\Column(name="id_utilisateur", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idUtilisateur;
/**
* #var \Site\UserBundle\Entity\Sexes
*
* #ORM\ManyToOne(targetEntity="Site\UserBundle\Entity\Sexes")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_sexe", referencedColumnName="id_sexe")
* })
*/
private $idSexe;
/**
* #var \Site\UserBundle\Entity\Niveaux
*
* #ORM\ManyToOne(targetEntity="Site\UserBundle\Entity\Niveaux")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_niveau", referencedColumnName="id_niveau")
* })
*/
private $idNiveau;`
As you can see I already have an "id_utilisateur" field which is the id of this entity.
And here is the code of the entity information in XML: The XML Code
Also here is a screenshot of the error I get when I try to log in: The Error
I think the problem is that per convention the id field is often called just id and in some places FOS UserBundle is expecting exactly that, e.g. in the UserProvider.
There are a few ways you can get around this. For instance you could just write your own UserProvder (using the one linked above as a reference) where you substitute the id with your field. You might have to do this in other places as well.
The easier solution would be to just change your entity to something like this:
/**
* #var integer
*
* #ORM\Column(name="id_utilisateur", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
public function getId() { return $this->id; }
Similarly in xml this would look like this:
<id name="id" column="id_utilisateur" type="integer">
<generator strategy="IDENTITY" />
</id>
This way in your entity you will use the expected property and accessor method, but in the background it will map to the database field id_utilisateur, so you you don't have to make any changes to your database.
This should already solve your problems. When a new user is generated Doctrine will take map $user->getId() to user_table.id_utilisateur automatically. If your existing code is making use of the old get-method you could just keep it around and mark it as deprecated:
/**
* #deprecated Use getId() instead.
*/
public function getIdUtilisateur()
{
return $this->getId();
}

Many to many relation with keeping old database

I have to rewrite application from zf1 to sf2.
But I need to keep old database schema.
And I have problem with many to many relations.
There are 2 entities: Exceptions, Regions and it was too Exceptionregions, but I deleted it.
There are 3 tables in database - exceptions, regions and exceptionregions, which is hash table.
Below I attach screen with relations:
My code:
1. Exception entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Exceptions
*
* #ORM\Table(name="Exceptions")
* #ORM\Entity
*/
class Exceptions
{
/**
* #var integer
*
* #ORM\Column(name="ExceptionID", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $exceptionid;
/**
* Many exceptions have many regions.
* #ORM\ManyToMany(targetEntity="Regions", inversedBy="exceptions")
* #ORM\JoinTable(name="exceptionregions"),
* joinColumns={#ORM\JoinColumn(name="ExceptionID", referencedColumnName="ExceptionID")},
* inverseJoinColumns={#ORM\JoinColumn(name="RegionID", referencedColumnName="RegionID")}
* )
*/
private $regions;
public function __construct()
{
$this->regions = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add region
*
* #param AppBundle\Entity\Regions $region
*/
public function addRegion(\AppBundle\Entity\Regions $regions)
{
$this->regions[] = $regions;
}
/**
* Get regions
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getRegions()
{
return $this->regions;
}
...
}
Region entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Regions
*
* #ORM\Table(name="Regions")
* #ORM\Entity
*/
class Regions
{
/**
* #var string
*
* #ORM\Column(name="RegionName", type="string", length=45, nullable=false)
*/
private $regionname;
/**
* #var integer
*
* #ORM\Column(name="RegionID", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $regionid;
/**
* #ORM\ManyToMany(targetEntity="Exceptions", mappedBy="regions")
*/
private $exceptions;
...
}
And I got this error:
The column id must be mapped to a field in class AppBundle\Entity\Exceptions since it is referenced by a join column of another class.
Of course entity Exceptions is connected with few entities, not only regions.
I got stuck with this issue, I can't resolve this problem and continue my project.
Anybody has any idea how to repair this or any advice? What am I doing wrong?
I'd be grateful for any comment.
I found a solution for this problem.
Maybe someone will benefit from this too.
So, the working code:
/**
* Many exceptions have many regions.
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Regions", inversedBy="exceptions")
* #ORM\JoinTable(name="exceptionregions",
* joinColumns={
* #ORM\JoinColumn(name="ExceptionID", referencedColumnName="ExceptionID")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="RegionID", referencedColumnName="RegionID")
* })
*/
private $regions;
#Alvin, thank you for your commitment.
Have you tried to make the relation bi-directional like so:
class Exceptions{
...
/**
* Many exceptions have many regions.
* #ORM\ManyToMany(targetEntity="Regions", inversedBy="exceptions")
* #ORM\JoinTable(name="regions_exceptions")
*/
private $regions;
class Regions{
...
/**
* #ORM\ManyToMany(targetEntity="Exceptions", mappedBy="regions")
*/
private $exceptions;
Not sure if that will work, but can you try it.
Documentation here:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-bidirectional
** EDIT #2 **
Can you try this change:
class Exceptions
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(name="ExceptionID", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $exceptionid;
Also, if that doesn't work, try:
php bin/console doctrine:schema:update --force

Php Doctrine OneToMany error : Undefined index in BasicEntityPersister.php

Hie there, after having past many times searching how I should have made an error, I have to ask now the question to the community since it is still a mystery.
I have here two tables : Solution and Project.
A solution can own N projects. A project can also be attached to no solution at all.
Here is part of the Solution.php file
/**
* Description of Solution
*
* #ORM\Entity(repositoryClass="X\Project\Repository\SolutionRepository")
* #ORM\Table(name="solution")
* #ORM\HasLifecycleCallbacks
*
* #author michel.strasser
*/
class Solution
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="bigint")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* [...]
*/
/**
* #var \Doctrine\Common\Collections\ArrayCollection
* #ORM\OneToMany(targetEntity="X\Project\Entity\Project", mappedBy="solution")
*/
private $projects;
/**
* [...]
*/
}
Here is part of the Project.php file :
<?php
namespace X\Project\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;
/**
* Description of Project
*
* #ORM\Entity(repositoryClass="X\Project\Repository\ProjectRepository")
* #ORM\Table(name="project")
* #ORM\HasLifecycleCallbacks
*
*/
class Project
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="bigint")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \X\Project\Entity\Solution
* #ORM\ManyToOne(targetEntity="X\Project\Entity\Solution", inversedBy="projects")
* #ORM\JoinColumn(name="solution", referencedColumnName="id", nullable=true, onDelete="SET NULL")
*/
private $solution;
}
I've got the following error :
Notice: Undefined index: solution in [...]\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php on line 1768
... when I try to access to $solution->getProjects()->toArray();
Any suggestion ? Please.
Bug found.
In fact there was no bug, I had to :
launch the 3 orm:clear-cache-* doctrine commands
delete the content of data/DoctrineModule/cache

Doctrine one-to-many relation - "No identifier/primary key specified"

Doctrine fails with a simple bi-directional many-to-one relationship between FoodDes (many) and FoodGroup (one). Both entities are shown here:
/**
* #ORM\Entity
* #ORM\Table(name="FOOD_DES")
*/
class FoodDes
{
public function __construct()
{
$this->foodGroup = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(name="NDB_No", type="string", length=10)
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="FoodGroup", inversedBy="fdGroupCode")
* #ORM\JoinColumn(name="FdGrp_Cd", referencedColumnName="FdGrp_CD")
*/
protected $foodGroup;
}
>
/**
* #ORM\Entity
* #ORM\Table(name="FD_GROUP")
*/
class FoodGroup
{
/**
* #ORM\Id();
* #ORM\GeneratedValue(strategy="NONE");
* #ORM\OneToMany(targetEntity="FoodDes", mappedBy="foodGroup")
*/
protected $fdGroupCode;
When I run doctrine orm:schema-tool:create, it fails with error:
No identifier/primary key specified for Entity
'Acme\Entities\FoodGroup'. Every Entity must have an
identifier/primary key.
However, I labeled $fdGroupCode as my only identifier.
Next approach
I've also tried creating a new primary key $id on the FoodGroup entity and removing the primary key label from $fdGroupCode on FoodGroup. Below is the new FoodGroup entity.
/**
* #ORM\Entity
* #ORM\Table(name="FD_GROUP")
*/
class FoodGroup
{
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer", nullable=false)
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="FoodDes", mappedBy="foodGroup")
*/
protected $fdGroupCode;
When I run doctrine orm:schema-tool:create again, it results with a new error:
[Doctrine\ORM\ORMException]
Column name FdGrp_CD referenced for relation from
Acme\Entities\FoodDes towards Acme\Entities\FoodGroup does not exist.
This error doesn't make any sense. Of course it wouldn't exist. I am running it against an empty database!
These error occur running from the command line, but they also occur when querying the entities against a database. Can somebody please help me?
I'd rather give you working example of OneToMany from one of my projects, so you can see the difference and format code in proper way. If it does not work, then try to get a new Symfony dist and start over.
<?php
// SomeBundle/Entity/Shop/Product.php
namespace SomeBundle\Entity\Shop;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="shop_products")
*/
class Product
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="bigint")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="ProductItem", mappedBy="product")
*/
protected $productItem;
}
Related entity:
<?php
// SomeBundle/Entity/Shop/ProductItem.php
namespace SomeBundle\Entity\Shop;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="shop_products_items")
*/
class ProductItem
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="bigint")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Product", inversedBy="productItem")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
protected $product;
}
For reasons why your code does not work could be many (namespaces, folder structure, column names, etc.). This example works and tested. Give it a try : )

Why association is not creating in Doctrine2?

I have 2 entities — NewsItem and Category. It is unidirectional association between this entities: 1 NewsItem has 1 Category, 1 Category has many NewsItem's.
I am trying to create association mapping like in THIS example. What I've tried? My code:
class NewsItem {
// other fields
/**
* #var int
* #ORM\Column(type="integer")
* #ORM\ManyToOne(targetEntity="News\Entity\Category")
*/
protected $category_id;
// other fiels, getters, setters etc
}
After that, I deleted tables in the database manually and run command orm:schema-tool:update --force in command line. It says that some queries are executed without errors — it's ok. But when I open table Category in HeidiSQL there are no FOREIGN KEYS there. That means that tables are not linked.
What I did wrong?
You can watch full code of this News\Entity\NewsItem entity here: click me. News\Entity\Category entity is here: click me.
you should remove * #ORM\Column(type="integer") as it is conflicting with the many-to-one relation.
Even if it is not the cause of the bug, you should also rename protected $category_id; to protected $category;
Also, your two entities are under the same namespace so it's not necessary to add the related entity's full path. targetEntity="Category" is enough.
You have incorrect mapping information for the Category entity.
Your NewsItem.php file should look like this:
namespace Your\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\JoinColumn;
/**
* #ORM\Table(name="news_item")
* #ORM\Entity
*/
class NewsItem {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Category
*
* #ORM\ManyToOne(targetEntity="Category", inversedBy="news_items")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
private $category;
// Rest of code omitted.
}
And your Category.php should look like this:
namespace Your\Bundle\Entity;
/**
* #ORM\Table(name="category")
* #ORM\Entity
*/
class Category {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="NewsItem", mappedBy="category")
*/
private $news_items;
public function __construct(){
$this->news_items = new ArrayCollection();
}
// Rest of code omitted.
}

Categories