Inversed foreign key doctrine - php

i have a OneToOne relation between my entity User and UserMeta
i would like to have access to UserMeta in User but set the foreign key in the UserMeta table in my mysql database:
class User implements UserInterface{
/**
* #ORM\Column(type="integer", unique=true)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="Foo\Bar\Entity\UserMeta", cascade={"persist"}, inversedBy="id_user")
* #ORM\JoinColumn(nullable=true)
* #ORM\Column(name="id_pro")
*/
private $proData;
}
class UserMeta{
/**
* #ORM\Column(type="integer", unique=true)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="Foo\Bar\Entity\User", mappedBy="id_pro")
* #ORM\JoinColumn(nullable=true)
* #ORM\Column(name="id_user")
*/
private $user;
}
Anyway to do that with doctrine ? I think i misunderstood mapped and inversed properties.

You mapping configuration is wrong.
In your User Class, it should read:
/**
* #ORM\OneToOne(targetEntity="Foo\Bar\Entity\UserMeta", cascade={"persist"}, inversedBy="user")
* #ORM\JoinColumn(nullable=true)
*/
private $proData;
and in your UserMeta Class, it should read:
/**
* #ORM\OneToOne(targetEntity="Foo\Bar\Entity\User", mappedBy="proData")
* #ORM\JoinColumn(nullable=true)
*/
private $user;
You also don't need the #ORM\Column directive since Doctrine2 will automatically do it for you.

Related

ORM Annotations in Symfony 6.0 - Add Multiple Constraints for Entity field

Using ORM Annotations in Symfony 6.0, I am trying to add the correct annotations to my entities so that I can output this SQL in a migration.
I am not sure how I am able to have both the group_id and the vendor_id match the id and vendor_id only using annotations.
ALTER TABLE `product_option_group_items`
ADD CONSTRAINT `FK123456` FOREIGN KEY (`group_id`, `vendor_id`)
REFERENCES `product_option_groups`(`id`, `vendor_id`)
ON DELETE RESTRICT ON UPDATE RESTRICT;
Up until now, I have manually modified the database to add the constraints, but would much prefer to have this added only using Symfony.
I have supplied the entities below.
I will add further business logic using #Constraints to the php code to validate if the groups vendor_id is that of the options vendor_id. I also want to know that this bug could not be inserted into the database in the event that a new migration file is created knocking out the constraints in the database that I manually updated after the fact.
I also do not want to have to add custom code to the migrations files, I would prefer to rely on doctrine:migrations:diff to assist me here.
Thanks in advance.
/**
* #ORM\Table(name="product_option_group_items")
*/
class ProductOptionGroupItemEntity
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private int $id;
/**
* #ORM\ManyToOne(
* targetEntity=ProductOptionGroupEntity::class
* )
* #ORM\JoinColumn(nullable=false)
*
*/
private ProductOptionGroupEntity $group;
/**
* #ORM\ManyToOne(
* targetEntity=ProductOptionEntity::class
* )
* #ORM\JoinColumn(nullable=false)
*/
private ProductOptionEntity $option;
/**
* #ORM\ManyToOne(
* targetEntity=VendorEntity::class
* )
* #ORM\JoinColumn(nullable=false)
*/
private VendorEntity $vendor;
}
/**
* #ORM\Entity(repositoryClass=VendorEntityRepository::class)
* #ORM\Table(name="vendors")
*/
class VendorEntity
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private int $id;
/**
* #ORM\ManyToOne(targetEntity=VendorTypeEntity::class)
* #ORM\JoinColumn(nullable=false)
*/
private VendorTypeEntity $type;
}
/**
* #ORM\Entity(repositoryClass=ProductOptionGroupEntityRepository::class)
* #ORM\Table(name="product_option_groups",
* indexes={
* #ORM\Index(name="Vendor_GroupId", columns={"id", "vendor_id"})
* })
*/
class ProductOptionGroupEntity
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private int $id;
/**
* #ORM\ManyToOne(
* targetEntity=VendorEntity::class,
* inversedBy="productOptionGroups"
* )
* #ORM\JoinColumn(nullable=false)
*/
private VendorEntity $vendor;
}
/**
* #ORM\Entity(repositoryClass=ProductOptionEntityRepository::class)
* #ORM\Table(name="product_options",
* indexes={
* #ORM\Index(columns={"id", "vendor_id"})
* })
*/
class ProductOptionEntity
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private int $id;
/**
* #ORM\ManyToOne(targetEntity=VendorEntity::class)
* #ORM\JoinColumn(nullable=false)
*/
private VendorEntity $vendor;
}

The association X refers to the inverse side field Y which is not defined as association

I have two entities:
Team:
class Teams
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer", name="id")
* #ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="team")
*
*/
private $id;
User:
class User implements UserInterface, \Serializable
{
/**
* #var int
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Teams", inversedBy="id")
* #ORM\JoinColumn(name="team_id", referencedColumnName="id")
*/
private $team;
One team have many users
And I've got these errors:
The association App\Entity\User#team refers to the inverse side field
App\Entity\Teams#id which is not defined as association.
The association App\Entity\User#team refers to the inverse side field
App\Entity\Teams#id which does not exist.
I don't know where I'm wrong... Anyone know ?
Regards
I'm bit confused of what you want to do.
If you want unidirectional relation from user side then remove
* #ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="team")
this code.
And user should have only
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Teams")
*/
private $teams;
On the other hand if you want bidirectional relation then add property user on teams entity.
It doesn't work for you because the mapping you defined is on $id and it should be on the property
Bidirectional way:
class Teams
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer", name="id")
*
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="teams")
* #ORM\JoinColumn(name="team_id", referencedColumnName="id")
*/
private $user;
class User implements UserInterface, \Serializable
{
/**
* #var int
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Teams", mappedBy="user")
*/
private $teams;
It's good practice to name entities with singular name so perhaps you'd like to change Teams to Team entity.
Check also http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-one-unidirectional
You want your Team to look like this:
class Team
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer", name="id")
*/
private $id;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\User")
*/
private $users;
This will generate teams of users. If you want your users to be able to on more than one team change your User call to a ManyToMany as well.
class User implements UserInterface, \Serializable
{
/**
* #var int
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Team")
*/
private $teams;

How to set a default value on a ManyToOne field for exsting entities

I am trying to add a ManyToOne column to an already existing table with rows in it.
I want it to be nullable=false!
Since it is not nullable, I'm trying to set a default value, but there is no option to do it.
If I don't set a default value, the shema update crashes and is not able to create the foreign key since there is no row with id of 0 in the table I created
The code of the table refered by the foreign key:
<?php
namespace MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints;
/**
* #ORM\Table(name="authority")
* #ORM\Entity()
*/
class Authority
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #Constraints\NotBlank(message="name cannot be blank.")
* #ORM\Column(type="string")
*/
protected $name;
/**
* #var \DateTime
*
* #ORM\Column(name="created_at", type="datetime", nullable=true)
*/
protected $createdAt;
/**
* Authority constructor.
*/
public function __construct()
{
$this->createdAt = new \DateTime();
}
}
The code of the table where I want to add the foreign key:
/**
* #var Authority
* #ORM\ManyToOne(targetEntity="MyBundle\Entity\authority", cascade={"persist"})
* #ORM\JoinColumn(referencedColumnName="id", nullable=false)
*/
protected $authority;
I tried:
protected $authority = 1;
or
* #ORM\JoinColumn(referencedColumnName="id", nullable=false, default=1)
or
public function __construct()
{
$this->authority = 1;
}
I don't want to have to change the database manually.
/**
* #var Authority
* #ORM\ManyToOne(targetEntity="MyBundle\Entity\authority", cascade={"persist"})
* #ORM\JoinColumn(referencedColumnName="id", nullable=false, columnDefinition="INT DEFAULT 1")
*/
protected $authority;
This do the trick in auto generated migration class.
You can set the default for the primary key of the referenced table. Look at the options={"default"=1}:
/**
* #ORM\Table(name="authority")
* #ORM\Entity()
*/
class Authority
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="integer", options={"default"=1})
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
#ORM\ManyToOne(targetEntity="App\Entity\Enumeration\TypeCompte")
#ORM\JoinColumn(name="IdTypeCompte", referencedColumnName="Id", nullable=false, columnDefinition="INT DEFAULT 1")
*/
private $typeCompte;

symfony2 combine primary key and relation

I'm trying to get a legacy database into the doctrine mappings.
All the tables have a combined primary key. One ID and one "optios id".
The problem is that Optios ID always has to be set but the OneToOne relation with the same columns causes the column "Optios ID" to be set to null. I'm not sure what I'm doing wrong or is there a way around it?
PS: The 'Pack' relation is optional.
<?php
namespace CalendarBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="CalendarBundle\Repository\CategoryRepository")
* #ORM\Table(name="Categories")
*/
class Category
{
/**
* #ORM\Id
* #ORM\Column(type="integer", name="Category_id")
*/
private $id;
/**
* #ORM\Column(type="integer", name="Optios_id")
* #ORM\Id
*/
private $optiosId;
/**
* #ORM\Column(type="string", name="Name")
*/
private $name;
/**
* #ORM\Column(type="boolean", name="AvailableOnline")
*/
private $online;
/**
* #ORM\Column(type="integer", name="SequenceNumber", nullable=true)
*/
private $order;
/**
* #ORM\Column(type="integer", name="Parent_id")
*/
private $parentId;
/**
* One Category has Many Packs.
*
* #var Pack
*
* #ORM\OneToOne(targetEntity="Pack", inversedBy="category")
* #ORM\JoinColumns(
* #ORM\JoinColumn(name="Pack_id", referencedColumnName="Pack_id"),
* #ORM\JoinColumn(name="Optios_id", referencedColumnName="Optios_id"),
* )
*/
private $pack;
/**
* #ORM\Column(type="boolean", name="Deleted")
*/
private $deleted;

Relationship between two intermediate entities in Symfony2

I have five entities :
ProductA, ProductB, User, UserProductA and UserProductB. The two last ones are "intermediate" entites which contain the attributes of relationships between ProductA, ProductB and User.
I would like to make a ManyToOne relationship between UserProductA and UserProductB but it doesn't work. When I try to update the database, I get this error : Single id is not allowed on composite primary key in entity.
UserProductA (without the relationship) :
/**
* #ORM\Entity(repositoryClass="Gam\UserBundle\Entity\UserProductARepository")
*/
class UserProductA
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Gam\FicheBundle\Entity\ProductA")
*/
private $producta;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Gam\UserBundle\Entity\User")
*/
private $user;
/**
* #ORM\Column(type="string", length=1, nullable=true)
*/
private $attribute;
etc...
}
UserProductB (without the relationship) :
/**
* #ORM\Entity(repositoryClass="Gam\UserBundle\Entity\UserProductBRepository")
*/
class UserProductB
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Gam\FicheBundle\Entity\ProductB")
*/
private $productb;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Gam\UserBundle\Entity\User")
*/
private $user;
/**
* #ORM\Column(type="string", length=1, nullable=true)
*/
private $attribute;
etc...
}
How can I make it work ?

Categories