I have a pretty STD Symfony2 project with FOSUserBundle installed.
Currently there is only basic user class took from FOS documentation:
<?php
// src/Acme/AppBundle/Entity/User.php
namespace Acme\AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
$this->setting = new \Doctrine\Common\Collections\ArrayCollection();
// your own logic
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
There is already a database and table based on this entity. What I am trying to do now is generate CRUD using command-line generator. But when I am generating CRUD with command:
php app/console generate:doctrine:crud
I am getting files with only ID field, it looks like that CRUD generator is not paying attention to parent class and its fields.
I guess it is not normal behavior, but I cannot find - why, what is happening ?
Any help will be appreciated...
Related
Is there a way to tell Doctrine the name of a number of entities and it creates their related tables (incl. foreign keys etc.)?
My scenario:
I want to have annotations at my Doctrine entities as the only source for my database schema. Which means, that for instance for tests, i don't want to maintain a copy of these information in a SQL file or something.
To be clear, i mean annotations in entity classes like the following:
<?php
namespace App\Entity;
/**
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #UniqueEntity(fields={"email"}, message="There is already an account with this email")
*
* #ORM\Table(
* uniqueConstraints={
* #ORM\UniqueConstraint(name="email", columns={"email"})
* }
* )
*/
class User
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=180, nullable=false)
*/
private $email;
// ...
}
What i would like to do:
In my tests i would like to create the table for, lets say User, like:
<?php
namespace App\Test;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class SomeTestCase extends KernelTestCase
{
public function setUp()
{
// ...
$this->entityManager = $kernel->getContainer()
->get('doctrine')
->getManager();
}
public function test1()
{
// Is there a function available which has this functionality?
$this->entityManager->createTableForEntity('App\Entity\User'); // <---------
// ...
}
}
Is that possible? If not, even creating all tables at once is fine for me.
Is there another way to achieve it?
I use the following to create all the tables in my tests:
use Doctrine\ORM\Tools\SchemaTool;
$metadatas = $this->entityManager->getMetadataFactory()->getAllMetadata();
$schemaTool = new SchemaTool($this->entityManager);
$schemaTool->updateSchema($metadatas);
There is a method getMetadataFactory() on the MetadataFactory class so I guess the following should work as well if you want to create just one table.
$metadata = $this->entityManager->getMetadataFactory()->getMetadataFor('App\Entity\User');
$schemaTool = new SchemaTool($this->entityManager);
$schemaTool->updateSchema($metadata);
i use doctrine ORM for generate a association one-to-many bidirectional, but when i execute the orm:validation-scheme command, this shows me the mesaje below:
"C:\xampp\htdocs\Gestor\vendor\bin>doctrine-module orm:validate-schema
[Mapping] FAIL - The entity-class 'Empleados\Entity\TipoDocumento' mapping is i
nvalid:
* The association Empleados\Entity\TipoDocumento#empleados refers to the owning
side field Empleados\Entity\Empleado#tipodocumento which does not exist.
[Database] FAIL - The database schema is not in sync with the current mapping fi
le."
The code:
Empleado class (many to one side)
<?php
namespace Empleados\Entity;
use Doctrine\Common\Collections\ArrayCollection as Collection;
use Empresas\Entity\Empresa;
use Empleados\Entity\TipoDocumento;
use Doctrine\ORM\Mapping as ORM;
use Documentos\Entity\Documentacion_Empleado;
/**
* #ORM\Entity
* #ORM\Table(name="empleado")
*
*/
class Empleado
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string",length=30,nullable=false,unique=true)
*/
private $nro_documento;
/*
* #ORM\ManyToOne(targetEntity="Empleados\Entity\TipoDocumento",inversedBy="empleados")
* #ORM\JoinColumn(name="tipodocumento_id", referencedColumnName="id")
*/
private $tipodocumento;
//...
}
The TipoDocumento class (one to many side):
<?php
// yes, the class are in the same namespace "Empleados"
namespace Empleados\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Empleados\Entity\Empleado;
/**
* #ORM\Entity
* #ORM\Table(name="tipo_documento")
*/
class TipoDocumento
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="Empleados\Entity\Empleado", mappedBy="tipodocumento"))
*/
private $empleados;
//.....
public function __construct()
{
$this->empleados = new ArrayCollection();
}
}
I'm based on the Doctrine documentation example in http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html
In class TipoDocumento, private $empleados; should be private $empleado;.
Edit
Sorry that's right, I was looking at the wrong place in the documentation.
The Many-to-one has the plural there. It also contains something like:
public function __construct() {
$this->empleados = new ArrayCollection();
}
I can't tell if your class contains this function.
jmarkmurphy thanks for your help.
The problem was in the camelcase of the "TipoDocumento" class, for some reason Doctrine does not like the camelcase ... What I did was rename the class to Tipo_documento and with that change everything started to work fine.
I'm working with Doctrine 2 as an ORM for Slim 3 but I keep getting stuck in the object mapping section when I try to implement a bidirectional relationship
/**
* Class Resource
* #package App
* #ORM\Entity
* #ORM\Table(name="users", uniqueConstraints={#ORM\UniqueConstraint(name="user_id", columns={"user_id"})}))
*/
class User
{
/**
* #ORM\ManyToOne(targetEntity="UserRoles", inversedBy="users")
* #ORM\JoinColumn(name="role_id", referencedColumnName="user_role_id")
*/
protected $user_role;
}
/**
* Class Resource
* #package App
* #ORM\Entity
* #ORM\Table(name="user_roles", uniqueConstraints={#ORM\UniqueConstraint(name="user_role_id", columns={"user_role_id"})}))
*/
class UserRoles
{
/**
* #ORM\OneToMany(targetEntity="User", mappedBy="user_role")
*/
protected $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
}
I get an exception when I try php vendor/bin/doctrine orm:schema-tool:update --force
The output is:
[Doctrine\Common\Annotations\AnnotationException][Semantical Error] The annotation "#OneToMany" in property App\Entity\UserRoles::$users was never imported. Did you maybe forget to add a "use" statement for this annotation?
Doctrine classes like
Column
Entity
JoinColumn
ManyToMany
ManyToOne
OneToMany
OneToOne
Full list available on Github
are part of the Doctrine\ORM\Mapping namespace.
You should import this namespace with ORM as an alias. Then you should add #ORM in front of these classes as annotation to make them work.
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\ManyToOne(...)
* #ORM\JoinColumn(...)
*/
If you just want to use every single of those classes you have to import each separately.
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\JoinColumn;
/**
* #ManyToOne(...)
* #JoinColumn(...)
*/
For my project, I'm trying to use the inheritance feature of Doctrine. I need to represent medias (through different tables : one table for uploaded documents, one for linked videos, ... and so on).
But, the videos can vary from provider to provider (such as Youtube, Dailymotion, you name it). So, I was thinking of doing another inheritance, proper to the Video table, through a SINGLE_TABLE inheritance.
But, when I declare my entities, it seems that if I add the SINGLE_TABLE inheritance annotation on the AbstractVideo entity, which extends the AbstractMedia Entity, the Video table is never created (nor detected). Here is a snippet of these two entities :
<?php
namespace Acme\Demo\Entity;
use Datetime;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="Media")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
*/
abstract class AbstractMedia
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// some other fields
}
/**
* #ORM\Entity
* #ORM\Table(name="Video")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="provider", type="string")
* #ORM\DiscriminatorMap({})
*/
abstract class AbstractVideo extends AbstractMedia
{
/** #ORM\Column(type="string") */
private $name;
// some other fields
}
I already tried to have a mapped entity to a Foo entity, extending the AbstractVideo, but then when I try to persist something, it says that it is not a valid entity.
Any ideas, or should I really avoid such deep inheritance ? Thanks
Not really sure if this is exactly what you need, but this is from a production code I use.
We inherit the file, with other entities, and those are also inherited.
The important part is to add the inheriting(extending) entities to disciminator map.
/**
* File
*
* #ORM\Table(name = "file")
* #ORM\Entity(repositoryClass="Living\ApiBundle\Entity\File\FileRepository")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string", length=64)
* #ORM\DiscriminatorMap({
* "file" = "Something\Entity\File\File",
* "image" = "Something\Entity\Image\Image",
* "specialImage" = "Something\Entity\Image\SpecialImage",
* })
*/
class File implements FileEntityInterface
.....
/**
* ImageFile
*
* #ORM\Table(name="image")
* #ORM\Entity(repositoryClass="Living\ApiBundle\Entity\Image\ImageRepository")
*/
class Image extends File implements ImageEntityInterface
As #OCramius said in a comment to my question, this is not supported by Doctrine ORM. So to do what I wanted to do, I will store a value object in the data property of my object, storing the property of "child classes" instead of having deep different kind of inheritance.
<?php
class Video extends AbstractMedia
{
// returns the value object youtube, dailymotion, ... etc
public function getData();
}
class Youtube
{
//public function ...
}
class Dailymotion
{
// public funciton ...
}
Im working with Symfony 2.4 im getting this exception when i came to run the code
doctrine:generate:entities
Class "Entity\ClientClass" is not a valid entity or mapped super class
How to resolve it.
Here is the code in Entity
namespace category\CategoryBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* category
*/
class category
{
/**
* #var integer
*/
private $id;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
We can't help you without details :
- check the namespace of the Entity/ClientClass and the file path according to doctrine configuration, by default : src/BundleName/Entity
does your class have the annotation #ORM\Entity or #ORM\MappedSuperClass ?