OneToMany Doctrine Symfony2 relationship issue - php

I have got a problem with OneToMany relation, I have user which can donate blood so he can have many blood donations, my application works fine but in my profiler I have 2 errors.
From Users Entity:
The association AppBundle\Entity\Users#userDonation refers to the owning side field AppBundle\Entity\UserDonates#id which is not defined as association, but as field.
The association AppBundle\Entity\Users#userDonation refers to the owning side field AppBundle\Entity\UserDonates#id which does not exist.
and from UserDonates:
The mappings AppBundle\Entity\UserDonates#userId and AppBundle\Entity\Users#userDonation are inconsistent with each other.
Here are my entities:
UserDonates:
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Users", inversedBy="userDonation")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $userId;
/**
* #var string
*
* #ORM\Column(name="place", type="string", length=255)
*/
private $place;
/**
* #var date
* #ORM\Column(name="donation_date", type="date")
*/
private $donation_date;
/**
* #var string
* #ORM\Column(name="donation_type", type="string", length=255)
*/
private $donation_type;
/**
* #var integer
* #ORM\Column(name="blod_donated", type="integer")
*/
private $blood_donated;
Users:
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="UserDonates", mappedBy="id", cascade={"persist","remove"})
*/
protected $userDonation;
/**
* #ORM\OneToOne(targetEntity="UserInfo", cascade={"persist","remove"})
*/
private $profil;
//__construct() from FOSUserBundle
public function __construct(){
parent::__construct();
}
Users entity is also related to UserInfo with OneToOne relation.

I see two issues here.
The association AppBundle\Entity\Users#userDonation refers to the owning side field AppBundle\Entity\UserDonates#id which is not defined as association, but as field.
The inverse side of your User::$userDonation association is not the id field, but the userId field in the UserDonation entity. The mapping should look like this:
/**
* Here! -----------------------------------------------v
* #ORM\OneToMany(targetEntity="UserDonates", mappedBy="userId", cascade={"persist","remove"})
*/
protected $userDonation;
As a side note, I'd suggest naming the userId attribute user instead; after all it will contain an actual user object, and not just a user's ID.
The association AppBundle\Entity\Users#userDonation refers to the owning side field AppBundle\Entity\UserDonates#id which does not exist.
Your UserDonates::$id attribute is private. All properties managed by Doctrine need to be protected in order for Doctrine to be able to populate them with data.

Related

Doctrine OneToMany Relation based on entityUid field

i'me working on a project with alot of the entities have string uid LIKE ENTITY.XXXX.
I'm seaching a way to relate some entities using doctrine annotations.
In particular the entity Media that contains all the links to the media files, to other entities becouse the relations between Media and the other entities like Document, Building etc is based on a field entityUid inside the Media entity, so the field entityUid is promiscuous becouse can contain the uid form different other entities.
I realize that cannot do a reverse mapping becouse i cant populate correctoy the reversed entity becouse is promiscuous, what i'm trying to do is a direct relation between for example Document 1:n Media based on Document.uid 1:n Media.entityUid and Bulding 1:n Media based on Document.uid 1:n Media.entityUid.
I write the entities:
class Media(){
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
*/
private $id;
/**
* #var string
* #ORM\Column(name="entityUid", type="string", nullable=false)
*/
private $entityUid;
/**
* #var string
*
* #ORM\Column(name="link", type="string", nullable=true)
*/
private $link;
... other stuff.
}
class Document(){
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
*/
private $id;
/**
*#var Media[]
*
*/
private $medias;
/**
* #var string
* #ORM\Column(name="uid", type="string", nullable=false)
*/
protected $uid;
... other stuff
}
class Building(){
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
*/
private $id;
/**
*#var Media[]
*
*/
private $medias;
/**
* #var string
* #ORM\Column(name="uid", type="string", nullable=false)
*/
protected $uid;
... other stuff
}
The problem is on the definition on the relation OneToMany, based not form the id fiels but uid fileds.
I was not able to find a correct annotation to create an unidirection OneToMany relation without creating a support table like a ManyToMany document_media , building_media, that would make useless the entities uids.
Tx for your time.

How to constrain saving id number as a value of field in ManyToOne Doctrine relation?

I have ManyToOne relation defined below.
Persisting owning side object, with inversed object setted in there, resulting in saving row in db of owning side where column that I expect to have value of id foreign key (integer) instead it save name (string) field of inversed table side.
In other words:
column iptra_documents.document_category_id contains value from iptra_document_category.name. I'm expecting to have iptra_document_category.id value in iptra_documents.document_category_id
Owning side:
/**
* #ORM\Table(name="iptra_documents")
*/
class IptraDocuments
{
/**
* #var int
*
* #ORM\Column(name="document_id", type="integer", unique=true)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $documentId;
/**
* #var IptraDocumentCategory
* #ORM\Column(name="document_category_id")
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\IptraDocumentCategory", inversedBy="id")})
*/
private $documentCategory;
//.....
public function setCategory(IptraDocumentCategory $documentCategory)
{
$this->documentCategory = $documentCategory;
}
Inverse side:
/**
* #ORM\Entity
* #ORM\Table(name="iptra_document_category")
*/
class IptraDocumentCategory
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(name="id", type="integer")
*/
private $id;
/**
* #ORM\Column(name="parent_id", type="integer")
*/
private $parentId;
/**
* #ORM\Column(name="name", type="string")
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\IptraDocuments", mappedBy="documentCategory")
*/
private $iptraDocuments;
According to the docs, you don't need #ORM\Column but #ORM\JoinColumn to define "Many" side
/**
* #var IptraDocumentCategory
*
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\IptraDocumentCategory", inversedBy="id")})
*/
private $documentCategory;

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;

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 :)

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