I am new to Symfony2 in general. This issue relates to Doctrine and FOSUserBundle though.
I have the following User.php Entity created based on FOSUserBundle and a self-referencing many-to many.
<?php
namespace Pan100\MoodLogBundle\Entity;
use FOS\UserBundle\Entity\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;
/**
* #ManyToMany(targetEntity="User", mappedBy="hasAccessToMe")
**/
protected $hasAccessTo;
/**
* #ManyToMany(targetEntity="User", inversedBy="hasAccessTo")
* #JoinTable(name="access",
* joinColumns={#JoinColumn(name="id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="accessor_id", referencedColumnName="id")}
* )
**/
private $hasAccessToMe;
public function __construct()
{
parent::__construct();
$this->hasAccessTo = new \Doctrine\Common\Collections\ArrayCollection();
$this->hasAccessToMe = new \Doctrine\Common\Collections\ArrayCollection();
}
}
Gives me the following error when attempting to update cache or drop:
[Doctrine\Common\Annotations\AnnotationException]
[Semantical Error] The annotation "#ManyToMany" in property Pan100\MoodLog
Bundle\Entity\User::$hasAccessTo was never imported. Did you maybe forget
to add a "use" statement for this annotation?
What is wrong here? And what is a "use statement"?
You forgot to add the #ORM\ prefix in your annotations:
/**
* #ManyToMany(targetEntity="User", mappedBy="hasAccessToMe")
**/
should be
/**
* #ORM\ManyToMany(targetEntity="User", mappedBy="hasAccessToMe")
**/
You could also import each annotation individually — the way I prefer:
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\ManyToMany;
// ...
/**
* #Entity
*/
class User
{
/**
* #ManyToMany(targetEntity="Thing")
*/
private $things;
// ...
}
Related
I read a lot Postings on Stackoverflow and the doctrine Documentation but i cannot find the error in this code. Maybe someone can lead me to the right direction as i'm sure i don't get the point on this concept. This is my first Project with doctrine.
I have three entities and the Database is generated correct but i always get these Errors when doing
php ./bin/console doctrine:schema:validate
the entities are as follows (shortened):
[FAIL] The entity-class App\Entity\DeployedTrap mapping is invalid: *
The association App\Entity\DeployedTrap#trapId refers to the inverse
side field App\Entity\TrapDefinition#id which is not defined as
association. * The association App\Entity\DeployedTrap#trapId refers
to the inverse side field App\Entity\TrapDefinition#id which does not
exist. * The association App\Entity\DeployedTrap#customer refers to
the inverse side field App\Entity\Customer#customerId which is not
defined as association. * The association
App\Entity\DeployedTrap#customer refers to the inverse side field
App\Entity\Customer#customerId which does not exist.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
*
* #ORM\Table(name="traps_deployed")
* #ORM\Entity(repositoryClass="App\Repository\DeployedTrapRepository")
*/
class DeployedTrap
{
/**
* #ORM\Column(name="id", type="integer", options={"unsigned"=true})
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* Owning side
* #ORM\JoinColumn(name="trap_id", referencedColumnName="id")
* #ORM\ManyToOne(targetEntity="TrapDefinition", inversedBy="id")
*/
public $trapId;
/**
* #ORM\JoinColumn(name="customer", referencedColumnName="customerId")
* #ORM\ManyToOne(targetEntity="App\Entity\Customer", inversedBy="customerId")
*/
private $customer;
}
Class TrapDefinition:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Table(name="traps_definition")
* #ORM\Entity(repositoryClass="App\Repository\TrapDefinitionRepository")
*/
class TrapDefinition
{
/**
* #ORM\Column(name="id",type="integer", options={"unsigned"=true})
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\OneToMany(targetEntity="DeployedTrap", mappedBy="trapId")
*/
public $id;
public function __construct()
{
$this->id = new ArrayCollection();
}
}
class Customer:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Events;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Table(name="customers")
* #ORM\Entity(repositoryClass="Doctrine\ORM\EntityRepository")
* #ORM\HasLifecycleCallbacks
*/
class Customer
{
/**
* #ORM\Column(type="integer",name="customerId",length=11, nullable=false, options={"unsigned"=true})
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\OneToMany(targetEntity="DeployedTrap", mappedBy="customer")
*/
public $customerId;
public function __construct()
{
$this->customerId = new ArrayCollection();
}
}
First: Forget the native database approach for linking Models via Id's (see $trapId in your DeployerTrap) in Doctrine. You will always link objects/collections to each other so $trapId should be $trapDefinition.
And that is your main problem here
Just add a field $deployerTraps to your TrapDefinition class
/**
* #ORM\OneToMany(targetEntity="DeployedTrap", mappedBy="trapDefinition")
*/
public $deployerTraps;
And rename the $trapId to $trapDefinition in your DeployedTrap class
/**
* #ORM\ManyToOne(targetEntity="TrapDefinition", inversedBy="deployerTraps")
*/
public $trapDefinition;
I'm trying to do a ManyToOne relation in Symfony2 with Doctrine. My entities are:
namespace My\ApiBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="company")
*/
class Company
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
public function __construct() {
$this->users = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
And the other one:
namespace My\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Entity\User as BaseUser;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User extends BaseUser
{
public function __construct()
{
parent::__construct();
}
/**
* #var
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
...
/**
* #ORM\ManyToOne(targetEntity="My\ApiBundle\Entity\Company")
* #ORM\JoinColumn(name="idLastCompany", referencedColumnName="id")
*/
protected $idLastCompany;
Obviusly with other attributes and their sets and gets methods, but my only relation is between Company with idLastCompany. When I clear cache for example, I get this error:
MappingException: The target-entity My\ApiBundle\Entity\Copmany cannot
be found in 'My\UserBundle\Entity\User#idLastCompany'.
Any Idea?
Thanks
The error message tells you everything you need :)
MappingException: The target-entity My\ApiBundle\Entity\ Copmany cannot be found in 'My\UserBundle\Entity\User#idLastCompany'.
You spelled CoPMany instead of Company either in the entity file name, in the entity class name or in the relation field $idLastCompany docblock.
Even though the code you posted here is correct, your actual code contains a typo.
I would search the entire project for "Copmany" and fix the typo. Then it will work.
I have this User entity extends from BaseUser:
namespace PDOneBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use PDOneBundle\Classes\Form\Validator\Constraints as GdcaAssert;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
/**
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
* #ORM\Table(name="fos_user")
* #ORM\Entity(repositoryClass="PDOneBundle\Entity\Repository\UserRepository")
* #Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false)
*/
class User extends BaseUser
{
/*
* Hook timestampable behavior
* updates createdAt, updatedAt fields
*/
use TimestampableEntity;
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var int
*
* #Assert\NotBlank()
*
* #ORM\ManyToOne(targetEntity="Company", inversedBy="users", cascade={"persist"})
* #ORM\JoinColumn(name="company_id", referencedColumnName="ID")
*/
protected $company;
/**
* #ORM\ManyToMany(targetEntity="Company", mappedBy="admins", cascade={"persist"})
*/
protected $companies;
/**
* #ORM\ManyToMany(targetEntity="Project", mappedBy="admins", cascade={"persist"})
*/
protected $projects;
// methods goes here
}
I am using also EasyAdminBundle and any time I try to add a new user from EasyAdmin I got the following error:
Neither the property "expiresAt" nor one of the methods
"getExpiresAt()", "expiresAt()", "isExpiresAt()", "hasExpiresAt()",
"__get()" exist and have public access in class
"PDOneBundle\Entity\User".
Why? It is not supposed that those methods are extended from BaseUser? Why the error?
It doesn't look like there is a getter for property expiresAt : https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Model/User.php
I guess you could easily add your own getter in your extended User class if EasyAdminBundle requires it.
class User extends BaseUser
{
// ...
public function getExpiresAt() {
return $this->expiresAt;
}
// ...
}
Looks like you could also define which properties EasyAdminBundle controls : https://github.com/javiereguiluz/EasyAdminBundle/blob/v1.2.1/Resources/doc/11-configuration-reference.md#advanced-configuration-with-custom-field-configuration
i try make onetoone relation from example - http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity
this is second try , first is here symfony 2 doctrine relation onetoone
Adres
<?php
/**
* Created by PhpStorm.
* User: grek
* Date: 18.12.13
* Time: 16:33
*/
namespace Miejsce\ObiektyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Adres {
/**
* #var integer
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=64, nullable=true)
*/
public $street;
/**
* #ORM\OneToOne(targetEntity="Miejsce\ObiektyBundle\Entity\User") */
private $user;
}
User
<?php
/**
* Created by PhpStorm.
* User: grek
* Date: 18.12.13
* Time: 16:33
*/
namespace Miejsce\ObiektyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class User {
/**
* #var integer
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=64, nullable=true)
*/
public $name;
/**
* #ORM\OneToOne(targetEntity="Miejsce\ObiektyBundle\Entity\Adres")
*/
private $adres;
}
and have : php app/console doctrine:schema:update --force
php app/console doctrine:schema:update --force
[Doctrine\Common\Annotations\AnnotationException]
[Semantical Error] The annotation "#Doctrine\ORM\Mapping" in property Miejsce\ObiektyBundle\Entity\Adres::$user does not e
xist, or could not be auto-loaded.
So where i can have error ?
error was in syntax - i have #ORM/OneToOne but need #ORM\OneToOne now work fine ! :)
The answer is in the error message. Look at what is different between your two classes.
/**
* #Entity
*/
Vs:
/**
* #ORM\Entity
*/
So update the one that is giving you the error.
edit
When you import Doctrine's annotations with use Doctrine\ORM\Mapping as ORM;, you'll need to start all those annotations with #ORM\. The annotation-reader will know that #ORM\Entity will actually mean #Doctrine\ORM\Mapping\Entity, which is the class that defines that annotation.
I'm not sure if I understand exactly what you are asking, but your annotations are not setup correctly.
/**
* #Entity
should become
/**
* #ORM\Entity
And
/**
* #Id #Column...
should become
/**
* #ORM\Id
* #ORM\Column...
Same for #OneToOne should be #ORM\OneToOne
Basically you are not prefixing your annotations correctly. You have use Doctrine\ORM\Mapping as ORM; but you aren't using it properly. Prefix your annotations and that will get you going.
I'm making entities with Symfony2 and Doctrine2. I made some entities that represent a many-to-many relation between two of my entities.
An example of one of these entities :
/**
* #ORM\Entity
*/
class Contact_Conference_Invitation
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Aurae\UserBundle\Entity\Contact")
*/
private $contact;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Aurae\ConferenceBundle\Entity\Conference")
*/
private $conference;
/**
* #var datetime dateInvitation
*
* #ORM\Column(name="dateInvitation", type="datetime")
*/
private $dateInvitation;
//Getters and setters
}
I have tried updating my sql schema, but the tables corresponding to these entities do not appear. Is there somewhere I have to declare them (config or such)? If not, what's wrong?
Thanks a lot
Edit : I had forgotten the namespace for these class, and that's why they were omitted by Doctrine. Another case closed :) thanks for the answers!
Assumptions ...
No, you don't need to declare them anywhere else than in your Entity directory.
What's the error message you got?
I guess you added
use Doctrine\ORM\Mapping as ORM;
on the top of your classes to let them be mapped.
I tried ...
I tried to generate your entities by adding a simple Contact & Conference entities and it's working fine.
Here are the code snippets:
Contact_Conference_Invitation.php
namespace Ahsio\StackBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Contact_Conference_Invitation
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Ahsio\StackBundle\Entity\Contact")
*/
private $contact;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Ahsio\StackBundle\Entity\Conference")
*/
private $conference;
/**
* #var datetime dateInvitation
*
* #ORM\Column(name="dateInvitation", type="datetime")
*/
private $dateInvitation;
//Getters and setters
}
Contact.php
namespace Ahsio\StackBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Contact
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #param $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Conference.php
namespace Ahsio\StackBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Conference
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #param $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Here are the generated tables:
NB: I used a specific namespace for the entities generation to work fine, you need to change them.
Also don't forget to check that you have automapping enabled.
In your config.yml you should have
doctrine:
orm:
auto_mapping: true
Came across this question because my entities weren't generated as well, this was my issue, it could save some time to people struggling with the same issue.
I don't see the definition of your ManyToMany relation in the sample of code you provided.
As an example, here's a ManyToMany relationship I implemented for a project
Entity Project.php
/**
* #var Provider[]
*
* #ORM\ManyToMany(targetEntity="Provider", mappedBy="projects")
*/
protected $providers = null;
Entity Provider.php
/**
* #var Project[]
*
* #ORM\ManyToMany(targetEntity="Project", inversedBy="providers")
* #ORM\JoinTable(name="PROVIDER_PROJECT")
*/
protected $projects = null;
As you can see, here you define the join table for your ManyToMany relationship.
Of course those entities are specific for my particular project but you get the idea and you can adapt it easily for your needs.