I followed this documentation in sonata, step by step and it worked.
Then I added a new entity and tried to generate a relation many to many to user entity, and when I validate it return this error
$ bin/console doctrine:schema:validate
Mapping
-------
[FAIL] The entity-class AppBundle\Entity\Business mapping is invalid:
* The association AppBundle\Entity\Business#user refers to the owning side field Application\Sonata\UserBundle\Entity\User#business which does not exist.
Database
--------
[OK] The database schema is in sync with the mapping files.
This are my two entities
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Business
*
* #ORM\Table(name="business")
* #ORM\Entity(repositoryClass="AppBundle\Repository\BusinessRepository")
*/
class Business
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="BusinessName", type="string", length=255)
*/
private $businessName;
/**
* #var string
*
* #ORM\Column(name="fantasyName", type="string", length=255)
*/
private $fantasyName;
/**
* #var string
*
* #ORM\Column(name="cuit", type="string", length=13)
*/
private $cuit;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\BankAccountType", inversedBy="business")
*/
private $bankAccountType;
/**
* #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;
/**
* #ORM\ManyToMany(targetEntity="\Application\Sonata\UserBundle\Entity\User", mappedBy="business")
*/
private $user;
/**
* #var bool
*
* #ORM\Column(name="isActive", type="boolean")
*/
private $isActive = true;
And this
namespace Application\Sonata\UserBundle\Entity;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* This file has been generated by the SonataEasyExtendsBundle.
*
* #link https://sonata-project.org/easy-extends
*
* References:
* #link http://www.doctrine-project.org/projects/orm/2.0/docs/reference/working-with-objects/en
*/
class User extends BaseUser
{
/**
* #var int $id
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="\AppBundle\Entity\Business", inversedBy="user")
* #ORM\JoinTable(name="business_user")
*/
private $business;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->business = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id.
*
* #return int $id
*/
public function getId()
{
return $this->id;
}
}
Any idea?
Here is my code for the same thing and it works.
class Role
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToMany(targetEntity="wizai\WMC\UserBundle\Entity\User", mappedBy="customRoles", fetch="EAGER")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
}
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="wizai\WMC\UserBundle\Entity\Role", inversedBy="users", fetch="EAGER")
* #ORM\JoinTable(name="user_role",
* joinColumns={#ORM\JoinColumn(name="user", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role", referencedColumnName="id")}
* )
*/
protected $customRoles;
/**
* User constructor.
*/
public function __construct()
{
$this->customRoles = new ArrayCollection();
}
}
if its still not possible, can you first run a migration or a force update ?
Commands
bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate
if not, then try.
bin/console doctrine:schema:update --force --complete
Related
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 following issue - I have one table, object_types in MySQL database and two Entities - Object and ObjectType in my Symfony 3.2 project. I have just synchronized the object types and now I want to do the same with objects with php bin/console doctrine:schema:update --complete command but it doesn't create a foreign key between tables.
Here is the Object class:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Object
*
* #ORM\Table(name="object")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ObjectRepository")
*/
class Object
{
/**
* #var int
*
* #ORM\Column(name="objectID", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $ID;
/**
* #var int
*
* #ORM\Column(name="object_typeID", type="integer")
* #ORM\ManyToOne(targetEntity="ObjectType")
* #ORM\JoinColumn(name="object_typeID", referencedColumnName="object_typeID")
*/
private $typeID;
/**
* #var string
*
* #ORM\Column(name="object_title", type="string", length=128)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="object_path", type="text")
*/
private $path;
/**
* #var bool
*
* #ORM\Column(name="object_active", type="boolean")
*/
private $active;
/**
* #var \DateTime
*
* #ORM\Column(name="object_added", type="datetime", nullable=true)
*/
private $added;
....
}
ObjectType:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ObjectType
*
* #ORM\Table(name="object_types")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ObjectTypeRepository")
*/
class ObjectType
{
/**
* #var int
*
* #ORM\Id
* #ORM\Column(name="object_typeID", type="integer", unique=true)
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $typeID;
/**
* #var string
*
* #ORM\Column(name="object_type_name", type="string", length=45)
*/
private $typeName;
How to achieve my goal?
Try below
ManyToOne
/**
* #var int
*
* #ORM\ManyToOne(targetEntity="ObjectType", inversedBy="object")
* #ORM\JoinColumn(name="object_typeID", referencedColumnName="id")
*/
private $typeID;
OneToMany
/**
* #ORM\OneToMany(targetEntity="Object", mappedBy="typeID")
*/
protected $object;
Your entities should be as below.
Object
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Object
*
* #ORM\Table(name="object")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ObjectRepository")
*/
class Object
{
/**
* #var int
*
* #ORM\Column(name="objectID", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $ID;
/**
* #var int
*
* #ORM\ManyToOne(targetEntity="ObjectType", inversedBy="object")
* #ORM\JoinColumn(name="object_typeID", referencedColumnName="id")
*/
private $typeID;
/**
* #var string
*
* #ORM\Column(name="object_title", type="string", length=128)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="object_path", type="text")
*/
private $path;
/**
* #var bool
*
* #ORM\Column(name="object_active", type="boolean")
*/
private $active;
/**
* #var \DateTime
*
* #ORM\Column(name="object_added", type="datetime", nullable=true)
*/
private $added;
....
}
ObjectType
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ObjectType
*
* #ORM\Table(name="object_types")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ObjectTypeRepository")
*/
class ObjectType
{
/**
* #var int
*
* #ORM\Id
* #ORM\Column(name="id", type="integer", unique=true)
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="object_type_name", type="string", length=45)
*/
private $typeName;
/**
* #ORM\OneToMany(targetEntity="Object", mappedBy="typeID")
*/
protected $object;
Hopefully it should work fine.
I have two entities relating to this issue, and I want a join table to be able to cross reference values in each table.
Here is an explanation:
Entity ContainerType.php:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Entity\Containers;
/**
* ContainerType
*
* #ORM\Table(name="container_type")
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
*/
class ContainerType
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="type", type="string", length=255)
*/
private $type;
/**
* #var \DateTime
*
* #ORM\Column(name="date_added", type="datetime")
*/
private $dateAdded;
/**
* #var \DateTime
*
* #ORM\Column(name="date_modified", type="datetime", nullable=true)
*/
private $dateModified;
/**
* #ORM\ManyToMany(targetEntity="Containers", inversedBy="type")
* #ORM\JoinTable(name="container_type_containers")
**/
private $container;
public function __construct()
{
$this->container = new ArrayCollection();
}
And entity Containers.php:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Entity\ContainerType;
/**
* Containers
*
* #ORM\Table(name="containers")
* #ORM\Entity
*/
class Containers
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="number", type="string", length=255)
*/
private $number;
/**
* #ORM\ManyToMany(targetEntity="Containers", mappedBy="container")
*/
private $type;
public function __construct()
{
$this->type = new ArrayCollection();
}
And although the schema update works without problems, when I do a doctrine:schema:validate I get the following fail:
[Mapping] FAIL - The entity-class 'AppBundle\Entity\Containers' mapping is invalid:
* The association AppBundle\Entity\Containers#type refers to the owning side field AppBundle\Entity\Containers#container which does not exist.
But the $container field DOES exist in ContainerType so I do not understand why it's trying to reference a field called container in the Containers entity?
Can anyone shed any light on this?
Thank you
Michael
I think this code should works fine for you :)
ContainerType.php
/**
* #ORM\ManyToMany(targetEntity="Containers", inversedBy="containersType")
* #ORM\JoinTable(name="container_type_containers",
* joinColumns={#ORM\JoinColumn(name="container_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="container_type_id", referencedColumnName="id")})
*/
protected $containers;
Containers.php
/**
* #ORM\ManyToMany(targetEntity="ContainerType", mappedBy="containers")
*/
protected $containersType;
I have just realized my error!
I had used the wrong target Entity in the Containers.php file, I should have used ContainerType as the target, instead I had Containers which is why it was trying to find the field in the wrong table!
Here some context information: I'm building a Symfony2 application with Doctrine2 and FOSRestBundle.
My problem: I want to be able to create a parent with his children with just one JSON and one database access.
My JSON looks like this:
{
"name": "TEST_NAME",
"info": "TEST_INFO",
"cmts": [
{
"cmt": "CMT1",
"info": "INFO1"
},
{
"cmt": "CMT2",
"info": "INFO2"
},
{
"cmt": "CMT3",
"info": "INFO3"
}
]
}
Here is my TEST entity:
<?php
namespace App\Bundle\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Test
*
* #ORM\Table(name="Test")
* #ORM\Entity(repositoryClass="App\Bundle\DemoBundle\Entity\TestRepository")
*/
class Test
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
* #Assert\NotBlank()
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="info", type="string", length=255, nullable=true)
*/
private $info;
/**
* #ORM\OneToMany(targetEntity="TestCmt", mappedBy="test", fetch="EAGER", orphanRemoval=true, cascade={"merge", "remove", "persist"})
*/
protected $cmts;
/**
* Constructor
*/
public function __construct()
{
$this->cmts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add cmts
*
* #param \App\Bundle\DemoBundle\Entity\TestCmt $cmts
* #return Test
*/
public function addCmt(\App\Bundle\DemoBundle\Entity\TestCmt $cmts)
{
$this->cmts[] = $cmts;
return $this;
}
/**
* Remove cmts
*
* #param \App\Bundle\DemoBundle\Entity\TestCmt $cmts
*/
public function removeCmt(\App\Bundle\DemoBundle\Entity\TestCmt $cmts)
{
$this->cmts->removeElement($cmts);
}
/**
* Get cmts
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCmts()
{
return $this->cmts;
}
// other getters/setters...
}
And my TESTCMT entity:
<?php
namespace App\Bundle\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* TestCmt
*
* #ORM\Table(name="TestCmt")
* #ORM\Entity(repositoryClass="App\Bundle\DemoBundle\Entity\TestCmtRepository")
*/
class TestCmt
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="cmt", type="string", length=255)
*/
private $cmt;
/**
* #var string
*
* #ORM\Column(name="info", type="string", length=255, nullable=true)
*/
private $info;
/**
* #var Test
*
* #ORM\ManyToOne(targetEntity="Test", inversedBy="cmts")
* #ORM\JoinColumn(name="test_id", referencedColumnName="id")
**/
private $test;
/**
* Set test
*
* #param \App\Bundle\DemoBundle\Entity\Test $test
* #return TestCmt
*/
public function setTest(\App\Bundle\DemoBundle\Entity\Test $test = null)
{
$this->test = $test;
return $this;
}
/**
* Get test
*
* #return \App\Bundle\DemoBundle\Entity\Test
*/
public function getTest()
{
return $this->test;
}
}
And finaly my postTestAction():
public function postTestAction(Request $request)
{
$entity = $this->deserialize($request, 'App\DemoBundle\Entity\Test');
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $entity;
}
When I send the JSON, TEST and TESTCMTs are created. Nevertheless, all "test_id" from the created TESTCMTs are "null"... And that's my problem!
EDIT: with SQL Server Profiler, I can see that Doctrine make that Transact SQL request:
INSERT INTO TESTCMT (test_id, cmt, info) VALUES (null, 'CMT', 'INFO')
I don't know why Doctrine can't send the test_id... TEST is created before TESTCMT, so "test_id" should be reachable for Doctrine to create the associate TESTCMTs.
Can someone helped me to fix it? :)
Remove #ORM\GeneratedValue(strategy="AUTO") and it won't let the DB generate a new id for the Entity
I updated my entity file to include relationship mapping.
Persist worked before the update now it doesn't.
Maybe it's something I forgot to do.
namespace classes\classBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* advisersplans
*
* #ORM\Table()
* #ORM\Entity
*/
class advisersPlans
{
/**
*
* #ORM\ManyToOne(targetEntity="plans", inversedBy="adviserPlans")
* #ORM\JoinColumn(name="planid", referencedColumnName="id")
*/
public $plan;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* #var integer
*
* #ORM\Column(name="userid", type="integer")
*
*
*/
public $userid;
/**
* #var integer
*
* #ORM\Column(name="adviserid", type="integer")
*
*
*/
public $adviserid;
/**
* #var integer
*
* #ORM\Column(name="planid", type="integer")
*
*
*/
public $planid;
/**
* #var string
*
* #ORM\Column(name="participantLoginWebsiteAddress", type="string", length=255)
*/
public $participantLoginWebsiteAddress;
public function __construct()
{
$class_vars = get_class_vars(get_class($this));
foreach ($class_vars as $key => $value)
{
if ($key != "plan")
$this->$key = "";
}
}
}
Perist returns error saying planid is null. If I remove the following it works.
/**
*
* #ORM\ManyToOne(targetEntity="plans", inversedBy="adviserPlans")
* #ORM\JoinColumn(name="planid", referencedColumnName="id")
*/
Here is my code while persisting.
$adviserPlan = new advisersPlans();
$adviserPlan->planid = $planid;
$adviserPlan->userid = $this->userid();
$adviserPlan->adviserid = $session->get("editadviserid");
$em->persist($adviserPlan);
Am I supposed to populate the plan field and not the planid field or is my entity file coded wrong.
You shouldn't set ids. You should set entities:
$adviserPlan = new advisersPlans();
// You should retrieve the plan before doing this, of course.
$adviserPlan->setPlan($plan);
$plans->addAdviserPlan(§adviserPlan);
$em->persist($adviserPlan);
The methods for adding an entity to a collection should be generated by doctrine when you run:
php app/console doctrine:generate:entities YourBundle