FOSUserBundle Entity with ManyToOne relation - symfony

I have AbstractUser super class that extends FOSUser, then I have entities that extends AbstractUser with fields related to that class. For instance Customer has ManyToOne relation to City entity.
Now when I try to log-in with FOSUser login form I'm getting error:
.... SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.city' in 'field list'
Of course there is no city field in the users table because it's relation column named city_id. Can anybody shed some light for me why doctrine builds query like this? Am I missing something ?
Thanks in advance.
Here is related code parts.
AbstractUser:
/**
* #ORM\Table(name="users")
* #ORM\Entity
* #ORM\MappedSuperclass
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="discr", type="string")
* #ORM\DiscriminatorMap({"admin"="Admin", "customer"="Customer", "seller"="Seller"})
*/
abstract class AbstractUser extends FOSUser
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
}
}
Customer:
/**
* #ORM\Entity
*/
class Customer extends AbstractUser {
....
/**
* #var City $city
* #ORM\ManyToOne(targetEntity="City", inversedBy="customers")
*/
private $city;
....
}
City:
/**
* #ORM\Table(name="city")
* #ORM\Entity
*/
class City
{
....
/**
* #var ArrayCollection $customers
* #ORM\OneToMany(targetEntity="Customer", mappedBy="city")
*/
private $customers;
....
}

I believe the visibility on $city and $customers has to be protected, not private.

I'm sorry for disturbance. This is my fault that I turned on doctrine cache (and impressed with results btw).
Almost scratched the hole in my head while trying to understand why this is happening. Luckily I ran into another error something woith doctrine and apc. Voila! That gave me a clue where to look.

Related

Symfony 6.1 Doctrine gives error 'Could not resolve type of column "id" of class "App\Entity\Officecurrencymax"'

I am getting the error Could not resolve type of column "id" of class "App\Entity\Officecurrencymax" from my installation. Have checked similar questions but I can't seem to get the Doctrine annotations right.
I have 2 entities with a ManyToOne relationship, Office and OfficeCurrencyMax. One Office can have many OfficeCurrencyMax's.
/**
* Office
*
* #ORM\Table(name="Office")
* #ORM\Entity(repositoryClass="App\Repository\OfficeRepository")
*/
class Office
{
// ...
/**
* #ORM\ManyToOne(targetEntity="Officecurrencymax", inversedBy="offices")
*/
private $officeCurrencyMaxes;
// ...
public function getOfficeCurrencyMaxes(): ?Officecurrencymax
{
return $this->officeCurrencyMaxes;
}
public function setOfficeCurrencyMaxes(?Officecurrencymax $officeCurrencyMaxes): self
{
$this->officeCurrencyMaxes = $officeCurrencyMaxes;
return $this;
}
}
Then there is the Officecurrencymax entity:
/**
* Officecurrencymax
*
* #ORM\Table(name="OfficeCurrencyMax", indexes={#ORM\Index(name="IDX_6F39111B73FD6E34", columns={"Office"})})
* #ORM\Entity(repositoryClass="App\Repository\OfficeCurrencyMaxRepository")
*/
class Officecurrencymax
{
// ...
/**
* #var integer
*
* #ORM\Column(name="Id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \Office
*
* #ORM\ManyToOne(targetEntity="Office", inversedBy="offices")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="Office", referencedColumnName="OfficeId")
* })
*/
private $office;
// ...
public function getId(): ?int
{
return $this->id;
}
// ...
}
I had to cut down the code a lot since StackOverflow wouldn't let me post since it looks like your post is mainly code, please add some more details.
In your case, you want to have 1-Office have Many-Officecurrencymax
So Office should have a OneToMany property and Officecurrencymax a ManyToOne.
There are a few errors, for example your Office entity says that the property is inversed by: inversedBy="offices" whereas $offices does not exist in the Officecurrencymax entity.
Your OneToMany in Office should look like:
/**
* #ORM\OneToMany(targetEntity=Officecurrencymax, mappedBy="office")
*/
private $officeCurrencyMaxes;
And in Officecurrencymax we have the opposite side of the relation:
/**
* #ORM\ManyToOne(targetEntity=Office, inversedBy="officeCurrencyMaxes")
* #ORM\JoinColumn(name="Office", referencedColumnName="OfficeId")
*/
private $office;
Do not forget to update the database schema.
based on these docs I would assume the default column name for your mapping should be id (note the case). You have capitalized your column name for some reason
#ORM\Column(name="Id" ...
I would suggest simply changing that to
#ORM\Column(name="id" ...

ORM Doctrine - JoinTable and JoinColumn "column not found" or "could not resolve type of the column"

I am a begginer in Doctrine and i am stuck in kind of a loop trying to establish a join table between 2 entities.
I have a relation OneToMany between a "train" and "containers" and ManyToOne between "containers" and "train" obviously.
I placed annotations on the OneToMany relation like this :
#ORM\Entity/Train
#ORM\OneToMany(targetEntity=Container::class, mappedBy="Train")
#ORM\JoinTable(name="train_container",
#ORM\joinColumns={#JoinColumn(name="id_tm", referencedColumnName="id_tm", nullable=false)},
#ORM\inverseJoinColumns={#JoinColumn(name="id_container", referencedColumnName="id_container", nullable=false)})
)
private $Container;
and on the ManyToOne i did like this :
#ORM\Entity/Container
#ORM\ManyToOne(targetEntity=Train::class, inversedBy="Containers")
#ORM\JoinColumn(name="id_tm", referencedColumnName="id_tm")
private $Train;
Now, if i let it like that, i have an error saying :
Annotation #ORM\joinColumns is not allowed to be declared on property App\Entity\Train::$container. You may only use this annotation on these code elements: PROPERTY.
If i remove the joinColumn and just put this :
#ORM\ManyToOne(targetEntity=Train::class, inversedBy="Container")
private $Train;
I have this error :
Could not resolve type of column "id" of class "App\Entity\Train"
I have no idea why its displaying an "id" column because the name of the column and the property on "Train" is always "id_tm" everywhere.
Could anyone tell me what i am doing wrong please ?
thanks a lot in advance
M
edit to add the code on the id's properties :
#ORM\Id
#ORM\GeneratedValue
#ORM\Column(type="integer", name="id_container")
private $id_container;
#ORM\Id
#ORM\GeneratedValue
#ORM\Column(type="integer", name="id_train")
private $id_train;
On the Train entity, you need to use the ManyToMany annotation with the unique parameter to get a OneToMany association as shown in the doctine documentation.
Here is the code that worked for me, try this:
Train Entity
/**
* Class Train
* #package App\Entity
* #ORM\Entity()
* #ORM\Table(name="train", options={"comment":"Train"})
*/
class Train
{
/**
* #var int
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id_train", type="integer", unique=true)
*/
private int $id_train;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Container", mappedBy="Train", cascade={"persist"})
* #ORM\JoinTable(name="train_container",
* joinColumns={#ORM\JoinColumn(name="train_id", referencedColumnName="id_train")},
* inverseJoinColumns={#ORM\JoinColumn(name="container_id", referencedColumnName="id_container", unique=true)}
* )
*/
private $Container;
public function __construct() {
$this->Container = new ArrayCollection();
}
//....
Also, if you want to have a bidirectional relationship between Container and Train entities, then you need to specify the following in the Container entity.
Container Entity
/**
* Class Container
* #package App\Entity
* #ORM\Entity()
* #ORM\Table(name="container", options={"comment":"Container"})
*/
class Container
{
/**
* #var int
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id_container", type="integer", unique=true)
*/
private int $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Train", inversedBy="Container")
* #ORM\JoinColumn(name="train_id", referencedColumnName="id_train")
*/
private $Train;
Don't forget to generate getters and setters after
php bin/console make:entity --regenerate
And update schema
php bin/console d:s:u -f

Doctrine Undefined index: UnitOfWork.php line 2873

I'm using FOSUserBundle with Symfony2. I'm attempting to use the Registration Email Confirmation functionality. When I hit the /confirmation/{confirmationToken} url Doctrine throws the following exception
Notice: Undefined index: 000000006553367d000000005133f603 in /Users/jacobspizziri/Documents/Projects/SRC3/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 2873
This occurs when it tries to hash the Group entity I constructed here:
spl_object_hash($entity)
and $entity looks like this:
Here are the relations I have setup in my entities:
/**
* #ORM\Entity
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*
* #author jacobspizziri
*/
class Group implements SoftDeletableInterface, TimestampableInterface {
/**
* #ORM\OneToMany(targetEntity="SRC\Bundle\UserBundle\Entity\User", mappedBy="group", cascade={"all"})
*/
protected $users;
}
/**
* #ORM\Entity
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class User extends BaseUser implements SoftDeletableInterface, TimestampableInterface
{
/**
* #ORM\ManyToOne(targetEntity="SRC\Bundle\UserBundle\Entity\Group", inversedBy="users")
* #ORM\JoinColumn(name="group_id", referencedColumnName="id")
*/
protected $group;
}
My bundle extends FOSUserBundle however I am not extending FOSUserBundle\Entity\Group for my Group
whats going on here?

How to avoid dependency with entities from different bundles

I have several bundles in my app and I would like to have relations between tables.
One is my User(StoreOwner) which is in UserBundle, and the second is Store in StoreBundle.
The relation between them is OneToMany (User -> is owner of -> Store).
Store
/**
* Description of Store
*
* #ORM\Table(name="Store")
* #ORM\Entity(repositoryClass="Traffic\StoreBundle\Repository\StoreRepository")
* #author bart
*/
class Store extends StoreModel {
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string $name
*
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank(
* message="Please provide your shop name"
* )
*/
protected $name;
/**
* #ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\StoreOwner", inversedBy="stores")
*
*/
protected $owner;
}
StoreOwner
/**
* #ORM\Entity
*
*/
class StoreOwner extends User implements StoreOwnerInterface {
/**
* #var type ArrayCollection()
*
* #ORM\OneToMany(targetEntity="Traffic\StoreBundle\Entity\Store", mappedBy="owner", cascade={"persist"})
*/
protected $stores;
}
My question is:
Is there any solution to avoid dependency between StoreBundle and UserBundle and keep relations between Entities in Doctrine?
This is a valid concern in my opinion. Two-way dependencies between bundles are a smell.
One way of solving the dependency issue is moving your entities out of the bundles into a more general namespace. This way both bundles will depend on the same "library" but won't depend on each other directly.
I recently wrote a blog post on how to do it: How to store Doctrine entities outside of a Symfony bundle?

Single Table Inheritance - discriminator map

I am needing to make a formula to DiscriminatorMap in my class, because I have a lot of class, and I can't discrimine each one.
The discr can be the name of the class.
it's possible? (with annotation, xml or other)
/**
* #ORM\Entity
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="discr", type="string")
* #ORM\DiscriminatorMap({"MidUpperArmCircumference" = MidUpperArmCircumference", "KneeHeight" = "KneeHeight"})
*/
thanks.
Look this link maybe it'll help you.
https://medium.com/#jasperkuperus/defining-discriminator-maps-at-child-level-in-doctrine-2-1cd2ded95ffb
I simply left out the DiscriminatorMap annotation and Doctrine automatically used the chield's class name as a discriminator:
/**
* #ORM\Entity()
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
*/
abstract class AbstractContent
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
}
/**
* #ORM\Entity()
*/
class Page extends AbstractContent
{
}
Now when I create a new Page() Doctrine creates an AbstractContentand a Page with an FK to the AbstractContent and sets the AbstractContent's type attribute to page.
This perfect as it let's you generate as many subclasses as you like even in other Bundles without your Superclass (in my case AbstractContent) needing to know about them.
But keep in mind that so far this isn't officially documented. Tested with Doctrine ORM 2.3.
This is an old question. Doctrine supports single table inheritance pretty well.
The below example is from official docs
<?php
namespace MyProject\Model;
/**
* #Entity
* #InheritanceType("SINGLE_TABLE")
* #DiscriminatorColumn(name="discr", type="string")
* #DiscriminatorMap({"person" = "Person", "employee" = "Employee"})
*/
class Person
{
// ...
}
/**
* #Entity
*/
class Employee extends Person
{
// ...
}
Read more about it here

Resources