There is a problem if I use $id in the MappedSuperclass?
I have the following schema, and I need to know if there is some problem use $id in the MappedSuperclass.
Thanks.
Example:
/**
* #ORM\MappedSuperclass
*/
abstract class AbstractBase
{
/**
* #var integer $id
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
-
/**
* #ORM\MappedSuperclass
*/
abstract class AbstractAddress extends AbstractBase
{
}
-
/**
* #ORM\Table(name="customer_address")
*/
class CustomerAddress extends AbstractAddress
{
}
-
/**
* #ORM\Table(name="order_address")
*/
class OrderAddress extends AbstractAddress
{
}
Related
I want to ultimately have an abstract base class that defines a relationship to another entity for all inheriting Entity-classes. So have this test-setup that was created with symfony's make:entity-command.
The only thing I changed was switching the MappedSuperClass's property-visibility from private to protected to make them visible to the extenders.
This is the MappedSuperClass:
[...]
/**
* Class TestMappedSuperclass
*
* #package App\Entity
* #ORM\MappedSuperclass()
*/
class TestMappedSuperclass
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity=TestTarget::class, mappedBy="testMappedSuperclass")
*/
protected $targets;
public function __construct()
{
$this->targets = new ArrayCollection();
}
//..getters/setters,add/remove...
}
This my target-entity for the mapping:
[...]
/**
* #ORM\Entity(repositoryClass=TestTargetRepository::class)
*/
class TestTarget
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity=TestMappedSuperclass::class, inversedBy="targets")
*/
private $testMappedSuperclass;
// ..getters,setters..
}
This is the extending entity class:
[...]
/**
* #ORM\Entity(repositoryClass=TestEntityRepository::class)
*/
class TestEntity extends TestMappedSuperclass
{
}
So when I try to do a make:migration it produces the following error:
Column name `id` referenced for relation from App\Entity\TestTarget towards
App\Entity\TestMappedSuperclass does not exist.
Using: Symfony 5.1, Doctrine 2.7
AFAIK you need to have repeat id as protected in TestEntity :
/**
* #ORM\Entity(repositoryClass=TestEntityRepository::class)
*/
class TestEntity extends TestMappedSuperclass
{
/**
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
I took this from a project where i´m using mappedSuperClass like this, i´m not relate entities in it though
I want to insert into my joint-table RoleUser idUser and idRole ,but in the function I should add an object user and role
How can I do that?
the joint table RoleUser :
/**
* RoleUser
*
* #ORM\Table(name="role_user", indexes={#ORM\Index(name="fk_role_user_id", columns={"ref_user_id"}), #ORM\Index(name="fk_role_id", columns={"ref_role_id"})})
* #ORM\Entity(repositoryClass="AppBundle\Repository\RoleUserRepository")
*/
class RoleUser
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \AppBundle\Entity\Role
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Role")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ref_role_id", referencedColumnName="id")
* })
*/
private $refRole;
/**
* #var \AppBundle\Entity\User
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ref_user_id", referencedColumnName="id")
* })
*/
private $refUser;
/**
* #param Role $refRole
*/
public function setRefRole(\AppBundle\Entity\Role $refRole)
{
$this->refRole = $refRole;
}
/**
* #param User $refUser
*/
public function setRefUser(\AppBundle\Entity\User $refUser)
{
$this->refUser= $refUser;
}
}
In my controller I want to insert the following (for a particular case I should insert in the background, the user can't choose his role):
$user = new User();
$role= new Role();
$roleUser =new RoleUser();
$roleUser->setRefUser($user->getId());
$roleUser->setRefRole(1);
but I konw that I should pass a user and a role :
$roleUser->setRefUser($user);
$roleUser->setRefRole($role);
You need to use a relation ManyToMany instead of OneToMany and remove your Entity RoleUser. you can follow the next example in the documentation official, to mapping this kind of relations.
For the save:
In this case you need to add in the two entities this relation:
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Location
*
* #ORM\Table(name="location")
* #ORM\Entity
*/
class Location
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* <p>Represent the </p>
* #ORM\ManyToMany(targetEntity="LogoLocation", mappedBy="locations")
*/
private $logoLocationCurse;
/**
* Location constructor.
*/
public function __construct()
{
$this->logoLocationCurse = new ArrayCollection();
}
public function addlogoLocationCurse(LogoLocation $location)
{
$this->logoLocationCurse->add($location);
$location->addLocations($this);
}
public function removeLogo(LogoLocation $location)
{
$this->logoLocationCurse->removeElement($location);
$location->removeLocation($this);
}
}
<?php
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use \DateTime;
/**
* Class LogoLocation
* #ORM\Table(name="logo_location_curso")
* #ORM\Entity
*/
class LogoLocation
{
/**
* #var integer
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* Many Users have Many Groups.
* #ORM\ManyToMany(targetEntity="Location", inversedBy="logocurso")
* #ORM\JoinTable(name="logo_locations")
*/
private $locations;
/**
* LogoLocation constructor.
*/
public function __construct()
{
$this->locations = new ArrayCollection();
}
/**
* #param Location $location
*/
public function addLocations(Location $location)
{
$this->locations->add($location);
}
/**
* #param Location $location
*/
public function removeLocation(Location $location)
{
$this->locations->removeElement($location);
}
/**
*
*/
public function removeLocations()
{
/** #var Location $location */
foreach ($this->locations as $location) {
$location->removeLogo($this);
}
}
}
and make the flush
I have #Embeddable class for id:
/**
* #ORM\Embeddable()
*/
final class Id
{
/**
* #ORM\Id()
* #ORM\Column(type="string")
*/
private $id;
//getters, setters, etc
}
And two classes that have #ManyToOne relationship:
/**
* #ORM\Entity()
*/
final class Gist
{
/**
* #var Id
*
* #ORM\Id()
* #ORM\Embedded(class="App\Entity\Id")
*/
private $id;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="App\Entity\User")
*/
private $user;
//getters, setters, etc
}
And User class:
/**
* #ORM\Entity()
*/
final class User implements UserInterface
{
/**
* #var Id
*
* #ORM\Embedded(class="App\Entity\Id")
*
*/
private $id;
//getters, setters, etc
}
When I trying to create schema I got error: No mapping found for field 'id' on class 'App\Entity\User'.. What I'm doing wrong?
There no solution. https://github.com/doctrine/doctrine2/issues/7094.
Support of identifiers within #Embeddable is not really there yet, sorry.
I suggest not to use #Embeddable on id field. Cause it won't work. Declare your id field normally and it should work.
/**
* #ORM\Entity()
*/
class Gist
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="App\Entity\User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
//getters, setters, etc
}
/**
* #ORM\Entity()
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
//getters, setters, etc
}
Also your Many-To-One relation is bad, see: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-one-unidirectional
And never declare entities as final classes, see: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/architecture.html#entities
Is it possible to keep an array of entities A in the entity A ? How to do this with Doctrine ?
I have :
class A {
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $sisters;
}
But I don't know what to add to have Doctrine do what I need.
A can have many sisters, and many sisters can be sister of A (Many-To-Many, Self-referencing):
/**
* #ORM\Entity()
* #ORM\Table()
*/
class A
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\A")
*/
private $sisters;
}
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-self-referencing
Trying to utilize inheritance, I've created the following entities:
/**
* #ORM\Table(name="persons")
* #ORM\Entity()
*/
class Person
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
protected $name;
/**
* #ORM\OneToOne(targetEntity="Image", cascade={"persist"})
* #ORM\JoinColumn(name="image_id", referencedColumnName="id")
*/
protected $image;
}
/**
* #ORM\Table(name="actors")
* #ORM\Entity()
*/
class Actor extends Person
{
/**
* #ORM\Column(name="character", type="string", length=255)
*/
private $character;
}
/**
* #ORM\Table(name="images")
* #ORM\Entity()
*/
class Image
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="path", type="string", length=255)
*/
private $path;
}
Which almost works perfectly. The generated actors-table contains all the persons-fields, except for the image-relation. I've tried to change the relation to a ManyToOne, which didn't help.
How to make the Actor-entity also inherit all joined fields? I'm open to other solutions, if the above isn't ideal.
You need a parent construct in your Actor class:
public function __construct()
{
parent::__construct();
// your own logic
}
It is advised that you add an ID aswell.