Doctrine won't join two columns- Using Symfony2 and Doctrine - php

I have two tables:
Posts
id | title | content | user
Users
id | name
and I want to have user name in Posts collection. What am I doing wrong here? Do I have to write custom query to do this?
Right now I'm getting user's id in posts collection.
class Posts
{
...
/**
* #ORM\Column(name="user", type="text", length=250)
* #ORM\ManyToOne(targetEntity="Users", inversedBy="posts")
* #ORM\JoinColumn(name="user", referencedColumnName="id")
*/
protected $user;
...
User class:
class Users
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="text", length=250)
*/
public $name;
/**
* #ORM\OneToMany(targetEntity="Posts", mappedBy="user")
*/
protected $posts;
...

you have an error in your $user relation annotation, you can't make a column be a regular #ORM\Column AND a #ORM\JoinColumn, try:
/**
* #ORM\ManyToOne(targetEntity="Users", inversedBy="posts")
* #ORM\JoinColumn(name="user", referencedColumnName="id")
*/
protected $user;
this will give you the entity(referencedColumnName must be primary key), then you can do $user->getName();

Related

Doctrine2 One to One Relation and extra table

I have 3 tables:
users, users_profile and extra table users_addresses.
User class:
class User
{
/**
* #ORM\Id()
* #ORM\Column(name="user_id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $userId;
/**
* #ORM\OneToOne(targetEntity="Entity\UserProfile", cascade={"persist", "remove"}, mappedBy="user", fetch="LAZY")
* #var Entity\UserProfile
*/
private $profile;
/**
* #param Entity\UserProfile $profile
*/
public function setProfile(UserProfile $profile) {
$this->profile = $profile;
$profile->setUser($this);
return $this;
}
(...)
}
User profile class
class UserProfile
{
/**
* #ORM\Id()
* #ORM\Column(name="profile_id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $profileId;
/**
* #ORM\OneToOne(targetEntity="Entity\User", inversedBy="profile")
* #ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
* #var Entity\User
*/
private $user;
/**
* #ORM\ManyToMany(targetEntity="Entity\Address", cascade={"persist"})
* #ORM\JoinTable(name="users_addresses",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="user_id")},
* inverseJoinColumns={#ORM\JoinColumn(name="address_id", referencedColumnName="address_id")}
* )
**/
private $addresses;
/**
* #param Address $address
*/
public function addAddress(Address $address) {
if (!$this->addresses->contains($address)) {
$this->addresses->add($address);
}
return $this;
}
(...)
}
Address class
class Address
{
/**
* #ORM\Id()
* #ORM\Column(name="address_id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #var int
*/
private $addressId;
/**
* #ORM\Column(type="string", length=128, nullable=false)
* #var string
*/
private $city;
(...)
}
Add user with profile data and address
$userAddress = new \Entity\Address();
$userAddress->setStreet($street);
$userAddress->setCity($city);
$userAddress->setCountry($country);
$userAddress->setState($state);
$userAddress->setZipCode($zipCode);
$userProfile = new \Entity\UserProfile();
$userProfile->addAddress($userAddress);
$user = new \Entity\User();
$user->setProfile($userProfile);
$em->persist($user);
$em->flush();
The problem i am having at the moment is that the entities persist ok, but the 'user_id' in the join table ('users_addresses') is not correct ('user_id' = 0, 'address_id' = correct). Table 'addresses' must not contain extra field like 'user_id'. What am I doing wrong?
I need a structure like this:
Your modeling shows that tables users and users_profile share the same primary key, namely user_id, and thus that column is also a foreign key toward users in users_profile.
Hence, you should replace profile_id in the Php annotations by user_id, remove the key auto generation directive, and update (or delete and recreate) the schema.
class UserProfile {
/**
* #ORM\Id
* #ORM\Column(name="user_id", type="integer")
* #var int
*/
private $profileId;
/* ... */
}
Then
$ doctrine orm:info --verbose
Found 3 mapped entities:
[OK] Address
[OK] User
[OK] UserProfile
$ doctrine orm:schema-tool:create
ATTENTION: This operation should not be executed in a production environmnent.
Creating database schema...
Database schema created successfully!
Or use the update command if you already have a schema.
You could also rename the php class attribute ($profileId), for "consistency" with the DB model, but I don't think it matters much, unless you have code which relies on a specific name.

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 ?

Symfony 2 relations issue

I nead help.
I have 3 entities. Book, Category And BookCategory - book can have multiple categories so i used another table.
I can easily acces Book and Category useing BookCategory table but i dont know how to do this by Book->BookCategory->Category.
class Category
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="text")
*/
private $name;
/**
* #var Category
* #ORM\ManyToOne(targetEntity="Category", inversedBy="Category")
* #ORM\JoinColumn(name="parent", referencedColumnName="id")
*/
private $parent;
class BookCategory
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Book
* #ORM\ManyToOne(targetEntity="Book", inversedBy="BookCategory")
* #ORM\JoinColumn(name="book_id", referencedColumnName="id")
*/
private $bookId;
/**
* #var Category
* #ORM\ManyToOne(targetEntity="Category", inversedBy="BookCategory")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
private $categoryId;
/**
* #var integer
*
* #ORM\Column(name="priority", type="integer")
*/
private $priority;
class Book
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="text")
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="author", type="text")
*/
private $author;
/**
* #var float
*
* #ORM\Column(name="price", type="float")
*/
private $price;
How i need to config my entities or how to make my DQL to achive wanted results?
With your code, you only established the relationship from BookCategory to Book. As you said, that enables you to get the Book associated to one BookCategory.
To go the other way and get all BookCategory that belong to one book, you also need to specify this relationship. What you want is a OneToMany relationship from Book to BookCategory.
<?php
//...
use Doctrine\ORM\Mapping\OneToMany;
class Book
{
//...
/**
* #OneToMany(targetEntity="BookCategory", mappedBy="bookId")
*/
private $bookCategories;
//...
}
class BookCategory
{
//...
/**
* #var Book
* #ORM\ManyToOne(targetEntity="Book", inversedBy="bookCategories")
* #ORM\JoinColumn(name="book_id", referencedColumnName="id")
*/
private $bookId;
//...
}
After adding the necessary getters and setters, getBookCategories() will give you an Array with all BookCategory that belong to the Book.
For more details, have a look at the official Symfony2 documentation:
http://symfony.com/doc/current/book/doctrine.html#relationship-mapping-metadata
Edit:
Included use statement. Corrected inversedBy property for bookId.

Inversed foreign key doctrine

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.

Doctrine/Symfony - I have some errors. Something wrong with my relations

I always get an exception with my entities. I tried to play with them. I checked on google which relation is the most appropriate for my entities... But I couldn't find the best configuration.
I'm making a website where you can create some albums.
A user can have multiple albums.So I have an entity Album and I have inside a user property :
/**
* Album
*
* #ORM\Table(name="album")
* #ORM\Entity(repositoryClass="Moodress\Bundle\AlbumBundle\Entity\AlbumRepository")
*/
class Album
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
** #ORM\ManyToOne(targetEntity="Moodress\Bundle\UserBundle\Entity\User")
** #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var \DateTime
*
* #ORM\Column(name="creationDate", type="datetime")
*/
private $creationDate;
/**
* #var \DateTime
*
* #ORM\Column(name="modificationDate", type="datetime")
*/
private $modificationDate;
/**
* #ORM\OneToMany(targetEntity="Moodress\Bundle\AlbumBundle\Entity\Picture", cascade={"persist"}, mappedBy="album")
*/
private $pictures;
/**
* Constructor
*/
public function __construct()
{
$this->creationDate = new \Datetime();
$this->modificationDate = new \Datetime();
}
// Get and set
}
However, When a user subscribe on the website, I create a default album called Upload that I want to keep in the user class.
This is what I tried to do :
/**
* User
*
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToOne(targetEntity="Moodress\Bundle\AlbumBundle\Entity\Album", cascade={"persist"})
*/
protected $albumUpload;
// Get and set
}
I have this error :
Undefined index: album in /Users/Sandro/sites/moodress-website/Symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1608. This error appears directly when I serialize any entity that has a user object...
The error is caused by the association annotation of the $albumUpload property in the User class.
Doctrine assumes that you have a $album property in your Album entity when you use a #ORM\OneToOne(targetEntity="Moodress\Bundle\AlbumBundle\Entity\Album") association in your User entity.
Try
/**
** #ORM\ManyToOne(targetEntity="Moodress\Bundle\UserBundle\Entity\User", inversedBy="albums")
** #ORM\JoinColumn(nullable=false)
*/
private $user;
in your Album entity and
/**
* #ORM\OneToMany(targetEntity="Moodress\Bundle\AlbumBundle\Entity\Album", mappedBy="user", cascade={"persist"})
*/
protected $albums;
in your User entity. In addition please add $this->albums = new ArrayCollection() to User::__construct().
Now if you want to add and keep a default album for users you should implement this somewhere in your business logic. You could figure out a way to identify the default album in your collection of albums and prevent deletion especially for this item.
Hope this helps.
My error:
'Undefined index: album'
results from this annotation in the Album class.
/**
* #ORM\OneToMany(
* targetEntity="Moodress\Bundle\AlbumBundle\Entity\Picture",
* cascade={"persist"},
* mappedBy="album"
* )
*/
I have set mappedBy to album but there is no $album property in my Picture class.
I did add this to my Picture class and clear my cache.
/**
* #ORM\ManyToOne(
* targetEntity="Moodress\Bundle\AlbumBundle\Entity\Album",
* inversedBy="pictures"
* )
*/
protected $album;
It solved my problem

Categories