Extending an entity class in doctrine - php

I'm trying to extend a class used as a doctrine entity, but for some reason I keep getting the error:
There is no column with name 'location_id' on table 'admin_subdivisions'
When I say extend, I mean at the php level NOT the database level. I simply want to create another table, with an extra column. I have several entities which extend the following abstract class
abstract class LocationProxy
{
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="Location", cascade={"ALL"}, fetch="LAZY")
* #ORM\JoinColumn(name="location_id", referencedColumnName="location_id", nullable=false)
*
* #var Location
*/
protected $location;
}
None of these second level classes give me any problems. Now, I want to extend this second level class
/**
* #ORM\Entity()
* #ORM\Table(name="admin_divisions")
*/
class AdminDivision extends LocationProxy
{
}
with this
/**
* #ORM\Entity()
* #ORM\Table(name="admin_subdivisions")
*/
class AdminSubDivision extends AdminDivision
{
}
but, it produces the error. Can anybody point out what I am doing wrong?
here is the Location class definition
/**
* #ORM\Entity()
* #ORM\Table(name="locations")
*/
class Location
{
/**
* #ORM\Id
* #ORM\Column(name="location_id", type="integer", options={"unsigned"=true})
*
* #var int
*/
private $id;
}

You must specify the inheritence type so that doctrine knows how to build the tables for the subclasses: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#mapped-superclasses
In you case you will need to add the following Annotations to your abstract LocationProxy Class:
#ORM\Entity
#ORM\InheritanceType("JOINED")
#ORM\DiscriminatorColumn(name="discr", type="string")
Or choose a different inheritance type
So the whole class will look like this:
/**
* #ORM\Entity
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="discr", type="string")
*/
abstract class LocationProxy {
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="De\Gregblog\Receipts\Location", cascade={"ALL"}, fetch="LAZY")
* #ORM\JoinColumn(name="location_id", referencedColumnName="location_id", nullable=false)
*
* #var Location
*/
protected $location;
}

Related

OneToMany ManyToOne DoctrineORM Error

I'm newbie with PHP. I started work with symfony but i have this problem
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #param \Doctrine\Common\Collections\Collection $carList
* #ORM\OneToMany(targetEntity="AppBundle\CarBundle\Entity\Car", mappedBy="name", cascade={"persist"})
*/
private $carList;
//getters and setters
}
*
* #ORM\Entity(repositoryClass="AppBundle\CarBundle\Repository\Entity\CarRepository")
* #ORM\Table(name="car")
*/
class Car
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*
*
*/
protected $id;
/**
* #ORM\Column(type="string", length=100)
* #ORM\ManyToOne(targetEntity="AppBundle\UserBundle\Entity\User" , inversedBy="carList")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $name;
//getters and setters
}
The stacktrace says:
Symfony\Component\Debug\Exception\ContextErrorException: Notice: Undefined index: name
at n/a
and when i run php bin/console doctrine:schema:validate
[Mapping] FAIL - The entity-class 'AppBundle\UserBundle\Entity\User'
mapping is invalid:
* The association AppBundle\UserBundle\Entity\User#carList refers to the owning side field AppBundle\CarBundle\Entity\Car#name which is not
defined as association, but as field.
*The association AppBundle\UserBundle\Entity\User#carList refers to the owning side field Appbundle\CarBundle\Entity\Car#name which does
not exist
I have no idea whats going on, can you help me?
You are mixing up association names with column names. When you create an association you don't need to manually add the columns for that association, doctrine will work that out for you.
This code (in the Car class) says that the $name field is a normal text column in the car table, which of course is wrong
* #ORM\Column(name="name",type="string", length=100)
What you're describing is that one user can own many cars, and many cars can belong to one user. I'd then call the associations owner and cars, but you are of course free to call them whatever you want. Note that you do not need to define the join columns.
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #param \Doctrine\Common\Collections\Collection $cars
* #ORM\OneToMany(targetEntity="AppBundle\CarBundle\Entity\Car", mappedBy="owner", cascade={"persist"})
*/
private $cars;
public function __construct()
{
$this->cars = new \Doctrine\Common\Collections\ArrayCollection();
}
//getters and setters
}
 
/**
*
* #ORM\Entity(repositoryClass="AppBundle\CarBundle\Repository\Entity\CarRepository")
* #ORM\Table(name="car")
*/
class Car
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\UserBundle\Entity\User" , inversedBy="cars")
*/
private $owner;
//getters and setters
}
Read more: Doctrine association mapping
Hope it makes sense :)

Doctrine 2 OneToOne from PFK of another OneToOne association

I have one question. I'm using Doctrine 2.0 and i want to know if is possible to made OneToOne association by using PFK created by another OneToOne assotiation as you can see on the picture below.
My code looks like this:
User class:
/**
* #ORM\Entity()
*/
class User extends \Kdyby\Doctrine\Entities\IdentifiedEntity
{
/**
* #ORM\OneToOne(targetEntity="AllianceMember", mappedBy="user")
* var AllianceMember
*/
protected $allianceMembership;
}
AllianceMember class:
/**
* #ORM\Entity()
*/
class AllianceMember extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="User", inversedBy="allianceMembership")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
* #var User
*/
protected $user;
/**
* #ORM\OneToOne(targetEntity="AllianceRole", mappedBy="allianceMember")
* var AllianceRole
*/
protected $role;
AllianceRole class:
/**
*
* #ORM\Entity()
*/
class AllianceRole extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="AllianceMember", inversedBy="role")
* #ORM\JoinColumn(name="role_id", referencedColumnName="user_id", nullable=false)
* #var AllianceMember
*/
protected $allianceMember;
}
I'm getting this error, when I'm trying to get instance of User entity:
The column user_id must be mapped to a field in class App\Entity\AllianceMember since it is referenced by a join column of another class.
Is it even possible?
Thanks.
Yes, using mapped entities for your #Id has been possible since doctrine 2.1 see Primary key and foreign key at the same time with doctrine 2
I think you simply need to remove some of your JoinColumn statements. Since #user is already designated as your #Id, it isn't necessary to specify user_id as the JoinColumn:
/**
* #ORM\Entity()
*/
class AllianceMember extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="User", inversedBy="allianceMembership")
* #var User
*/
protected $user;
/**
* #ORM\OneToOne(targetEntity="AllianceRole", mappedBy="allianceMember")
* var AllianceRole
*/
protected $role;
and
/**
*
* #ORM\Entity()
*/
class AllianceRole extends \Kdyby\Doctrine\Entities\BaseEntity
{
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="AllianceMember", inversedBy="role")
* #var AllianceMember
*/
protected $allianceMember;
}
The id of the AllianceMember is the user_id, and the id of the AllianceRole is the id of the AllianceMember, which is user_id.

Doctrine one-to-many relation - "No identifier/primary key specified"

Doctrine fails with a simple bi-directional many-to-one relationship between FoodDes (many) and FoodGroup (one). Both entities are shown here:
/**
* #ORM\Entity
* #ORM\Table(name="FOOD_DES")
*/
class FoodDes
{
public function __construct()
{
$this->foodGroup = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(name="NDB_No", type="string", length=10)
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="FoodGroup", inversedBy="fdGroupCode")
* #ORM\JoinColumn(name="FdGrp_Cd", referencedColumnName="FdGrp_CD")
*/
protected $foodGroup;
}
>
/**
* #ORM\Entity
* #ORM\Table(name="FD_GROUP")
*/
class FoodGroup
{
/**
* #ORM\Id();
* #ORM\GeneratedValue(strategy="NONE");
* #ORM\OneToMany(targetEntity="FoodDes", mappedBy="foodGroup")
*/
protected $fdGroupCode;
When I run doctrine orm:schema-tool:create, it fails with error:
No identifier/primary key specified for Entity
'Acme\Entities\FoodGroup'. Every Entity must have an
identifier/primary key.
However, I labeled $fdGroupCode as my only identifier.
Next approach
I've also tried creating a new primary key $id on the FoodGroup entity and removing the primary key label from $fdGroupCode on FoodGroup. Below is the new FoodGroup entity.
/**
* #ORM\Entity
* #ORM\Table(name="FD_GROUP")
*/
class FoodGroup
{
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer", nullable=false)
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="FoodDes", mappedBy="foodGroup")
*/
protected $fdGroupCode;
When I run doctrine orm:schema-tool:create again, it results with a new error:
[Doctrine\ORM\ORMException]
Column name FdGrp_CD referenced for relation from
Acme\Entities\FoodDes towards Acme\Entities\FoodGroup does not exist.
This error doesn't make any sense. Of course it wouldn't exist. I am running it against an empty database!
These error occur running from the command line, but they also occur when querying the entities against a database. Can somebody please help me?
I'd rather give you working example of OneToMany from one of my projects, so you can see the difference and format code in proper way. If it does not work, then try to get a new Symfony dist and start over.
<?php
// SomeBundle/Entity/Shop/Product.php
namespace SomeBundle\Entity\Shop;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="shop_products")
*/
class Product
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="bigint")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="ProductItem", mappedBy="product")
*/
protected $productItem;
}
Related entity:
<?php
// SomeBundle/Entity/Shop/ProductItem.php
namespace SomeBundle\Entity\Shop;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="shop_products_items")
*/
class ProductItem
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="bigint")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Product", inversedBy="productItem")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
protected $product;
}
For reasons why your code does not work could be many (namespaces, folder structure, column names, etc.). This example works and tested. Give it a try : )

Doctrine2 cascade delete doesn't work with Abstract Class

In my web application, which is built with Symfony2, contains the following entities:
/**
* #ORM\Entity
* #ORM\Table
*/
class Entity
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="MappedSuperclass", mappedBy="entity", cascade={"persist", "remove"})
*/
private $mappedSuperclasses;
}
/**
* #ORM\MappedSuperclass
*/
abstract class MappedSuperclass
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Entity", inversedBy="mappedSuperclasses")
* #ORM\JoinColumn(name="entity_id", referencedColumnName="id", nullable=false)
*/
protected $entity;
}
/**
* #ORM\Entity
* #ORM\Table(name="table_1")
*/
class Subclass1 extends MappedSuperclass
{
/**
* #ORM\Column(name="unique_member", type="string")
*/
private $uniqueMember;
}
/**
* #ORM\Entity
* #ORM\Table(name="table_2")
*/
class Subclass2 extends MappedSuperclass
{
/**
* #ORM\Column(name="unique_member", type="string")
*/
private $uniqueMember; // This is different from Subclass1
}
I'll explain this a bit. An Entity has a collection of MappedSuperclass. MappedSuperclass is an abstract class which contains some common variables for its subclasses. Subclass1 and Subclass2 are subclasses of MappedSuperclass. When an Entity is removed from database, the items in $mappedSuperclasses should be removed together, that's why the cascade={"persist", "remove"} is set.
However, when I try to delete an Entity, I got the following error:
ContextErrorException: Notice: Undefined index: entity in C:\project\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php line 1753
If I change the targetEntity of Entity::$mappedSuperclasses to Subclass1 or Subclass2, it will work. Is my set up impossible to achieve ON DELETE CASCADE? What am I missing?
I solved this problem by setting the ON DELETE action to database level:
/**
* #ORM\Entity
* #ORM\Table
*/
class Entity
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
private $id;
}
/**
* #ORM\MappedSuperclass
*/
abstract class MappedSuperclass
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="Entity")
* #ORM\JoinColumn(name="entity_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*/
protected $entity;
}
Sources: [1] [2]
Im answering year after the issue was resolved but I had the same problem. Error occurs when I tried to empty count arrayCollection.
So the solution was to check if $this->entity is array and then return its length.

Doctrine and inheritance mapping: association on a child entity

I'm trying to query an entity and joined an other entity which is a child in an inheritance mapping structure.
The situation is:
I have a parent entity (eg. Animal)
I have a child entity (eg. Dog)
I have an entity with a 1:1 association to the child (Dog House)
I want to query all the dog houses and doctrine to get me their dog owners as well.
The simple DQL query I wrote is:
SELECT o FROM MyBundle:DogHouse h JOIN h.dog d
The error is:
Notice: Undefined index: id in
../vendor/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php
line 779, class: ErrorException
Looking at the stack trace it seems that doctrine is trying to join with the id on the child entity instead of the parent
Here is the classes illustrating this case
/**
* Animal
*
* #ORM\Entity
* #ORM\Table(name="animal")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="integer")
* #ORM\DiscriminatorMap({"1"="cat", "2"="dog"})
*/
class Animal
{
/**
* #ORM\Column(name="animal_id", type="integer", nullable=false)
* #ORM\Id
*/
protected $id;
/**
* #ORM\Column(name="name", type="string", length=200, nullable=false)
*/
protected $name;
/* getters, setters... */
}
/**
* Dog
*
* #ORM\Entity
* #ORM\Table(name="dog")
*/
class Dog extends Animal
{
/**
* #ORM\OneToOne(targetEntity="DogHouse", inversedBy="dog")
*/
private $dogHouse;
/* getters, setters... */
}
/**
* Dog House
*
* #ORM\Table(name="dog_house")
* #ORM\Entity
*/
class DogHouse
{
/**
* #ORM\Column(name="dog_house_id", type="integer", nullable=false)
* #ORM\Id
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="Dog", mappedBy="doghouse")
*/
private $dog;
/* getters, setters... */
}
Note:
This post relates to the exact same problem and wasn't answered
Your mappings are set up incorrectly...
The one To one relation between Dog / Doghouse should be as follows..
class DogHouse....
/**
* #ORM\OneToOne(targetEntity="Dog", mappedBy="doghouse")
*/
private $dog;
Make sure your mappedBy="doghouse"

Categories