one to many relationship problem in doctrine 2.0 - php

I have an events table and events images table. I am having a form to add new event so i am also adding multiple images for that event. So that i am storing in event images table.
so how do i insert the data in both the tables..
<?php
/**
* #Entity
* #Table(name="events")
*/
class Default_Model_Event
{
/**
* #Id #Column(name="id", type="integer")
* #GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #Column(name="title", type="string")
*/
private $title;
/**
* #OneToMany(targetEntity="Default_Model_EventImages" mappedBy="eventimage_mapper")
*/
private $images_mapper;
}//end class
Event images model
<?php
/**
* #Entity
* #Table(name="event_images")
*/
class Default_Model_EventImages
{
/**
* #Id #Column(name="id", type="integer")
* #GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #Column(name="name", type="string")
*/
private $name;
/**
* #ManyToOne(targetEntity="Default_Model_Event", inversedBy="images_mapper")
* #JoinColumn(name="event_id", referencedColumnName="id")
*/
private $eventimage_mapper;
}//end class
From my controller how do i save the data now.. I am thinking of first saving the event data and than will get that id and than will save the events images by loop.. than i am not getting what will be the use of the one to many mapper i have created..
I am using zend framework 1.11 and Doctrine 2.0

At first you need to create getters, setters to your objects. Then you just create
$event = new Default_Model_Event();
$em->persist($event);
while (something) {
$image = new Default_Model_EventImages();
$image->setEventimage_mapper($event);
$em->persist($image);
}
$em->flush();
Just read the Doctrine documentation on associations. It will help for sure.

Related

Inverse sides always returns an empty collection for a ManyToMany relationship

This is something I've done before, so I'm quite confused as to why it's not working.
I have two entities Question and Qresponse. Question is the owning side and Qresponse is the inverse side. When I use doctrine to find all Questions, the qresponses property is always empty.
//$questions is populated, but the qresponses property is always empty
$questions = $this->getDoctrine()->getManager()->getRepository(Question::class)->findAll();
Why is it empty ? What am I doing wrong?
Snippet of Owning side: Question
/**
* Class Question
* #package Entity
*
* #ORM\Entity
*/
class Question
{
public function __construct()
{
$this->qresponses = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/** #var ArrayCollection $responses
* #ORM\ManyToMany(targetEntity="Qresponse", mappedBy="questions", cascade={"persist"})
*/
private $qresponses;
}
Snippet of Inverse side: Qresponse
/**
* Class Response
* #package Entity
*
* #ORM\Entity
*/
class Qresponse
{
public function __construct()
{
$this->questions = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var ArrayCollection $question
* #ORM\ManyToMany(targetEntity="Question", inversedBy="qresponses", cascade={"persist"})
* #ORM\JoinTable(name="qresponse_question")
*/
private $questions;
}
Image of database that is populated.
Image from the profiler in symfony showing that qresponses is empty...
You are doing nothing wrong, it's just a typical doctrine hydration issue.
Doctrine by default uses lazy loading, that means associations are only loaded when needed (e.g. when $question->getQResponses()->first()->getId() is called). You can easily change it by setting doctrine fetch option to EAGER in your association:
/**
* #var ArrayCollection $responses
* #ORM\ManyToMany(targetEntity="Qresponse", mappedBy="questions", cascade={"persist"}, fetch="EAGER")
*/
private $qresponses;

Symfony doctrine many to many unique

I have to entity with manyToMany relation, that i have transform in two OneToMany. So I have create an other Entity called CollanaCollezionista into that i have some attribute.
I want that the couple collana/collezionista is unique, how can i do this on doctrine and symfony?
/**
* Collana
*/
class Collana
{
private $id;
private $titolo;
/**
* #MaxDepth(1)
* #ORM\OneToMany(targetEntity="CollezionistaCollana", mappedBy="collana")
*/
private $collezionisti;
}
/**
* Collezionista
*/
class Collezionista
{
private $id;
private $user;
/**
* #ORM\OneToMany(targetEntity="CollezionistaCollana", mappedBy="collezionista")
*/
private $collane;
}
So I have an other entity, called CollezionistaCollana. How can i set that the couple collezionista-collana is unique?
Answer:
#UniqueConstraint do the stuff.
use Doctrine\ORM\Mapping\UniqueConstraint as UniqueConstraint;
/**
* CollezionistaCollana
*
* #ORM\Table(name="collezionista_collana",uniqueConstraints={#‌UniqueConstraint(nam‌​e="unique_hold", columns={"idCollezionista", "idCollana"})})
* #ORM\Entity
*/
class CollezionistaCollana
{
// Class details
}

Symfony2 and doctrine: multiple relationships between two classes

I am new to Symfony2 and Doctrine.
I have two classes: User and Book. Each user can like very much, quite, or dislike every book in the database.
In order to describe this kind of association, I defined three different ManyToMany relationships between the two classes.
Here is an extract of my code:
Here is class User
<?php
namespace MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="MyBundle\Entity\UserRepository")
*/
class User
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=64, unique=true)
*/
private $username;
/**
* #ORM\ManyToMany(targetEntity="Book", inversedBy="user_likemuch")
* #ORM\JoinColumn(name="book_id", referencedColumnName="id")
*/
protected $books_likemuch;
/**
* #ORM\ManyToMany(targetEntity="Book", inversedBy="user_likequite")
* #ORM\JoinColumn(name="book_id", referencedColumnName="id")
*/
protected $books_likequite;
/**
* #ORM\ManyToMany(targetEntity="Book", inversedBy="user_dislike")
* #ORM\JoinColumn(name="book_id", referencedColumnName="id")
*/
protected $books_dislike;
public function __construct()
{
$this->books_likemuch = new ArrayCollection();
$this->books_likequite = new ArrayCollection();
$this->books_dislike = new ArrayCollection();
}
}
And here is class Book:
<?php
namespace MyBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Book
*
* #ORM\Table(name="book")
* #ORM\Entity(repositoryClass="MyBundle\Entity\BookRepository")
*/
class Book
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=64)
*/
private $name;
/**
* #ORM\ManyToMany(targetEntity="User", mappedBy="books_likemuch")
*/
protected $user_likemuch;
/**
* #ORM\ManyToMany(targetEntity="User", mappedBy="books_likequite")
*/
protected $user_likequite;
/**
* #ORM\ManyToMany(targetEntity="User", mappedBy="books_dislike")
*/
protected $user_dislike;
public function __construct() {
$this->user_likemuch = new ArrayCollection();
$this->user_likequite = new ArrayCollection();
$this->user_dislike = new ArrayCollection();
}
}
However, when I try to update the schema of the database through
php app/console doctrine:schema:update --force
I get the following error:
[Doctrine\DBAL\Schema\SchemaException]
The table with name 'XXX/myproject/app/data/users.user_book' already exists.
Actually, I do not even understand if I an describing the relationship in a wrong way, or if doctrine cannot manage multiple relationships between two classes.
Does anyone have any suggestion?
Thanks in advance!
Doctrine can indeed manage multiple relationships. The classic example is between Users and Roles. The problem here is that you're trying to create multiple ManyToMany relationships between the same two entities. What Doctrine will do to manage these relationships is create a "join" table using the convention table1_table2, or in your case "user_book". So the reason you are getting the Doctrine error is ostensibly because it's attempting to create the same table 3 times.
I think what you want to do is have 3 separate ManyToMany "join" tables, one for likemuch, likequite, and dislike. So try specifying the join table for each association and see if that helps. Ex:
/**
* #ORM\ManyToMany(targetEntity="Book", inversedBy="user_likemuch")
* #ORM\JoinColumn(name="book_id", referencedColumnName="id")
* #ORM\JoinTable(name="user_book_likemuch")
*/
protected $books_likemuch;
See the section on bi-directional association mapping for ManyToMany relationships: Doctrine Association Mapping

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

Symfony2 : Entities not created in database

I'm making entities with Symfony2 and Doctrine2. I made some entities that represent a many-to-many relation between two of my entities.
An example of one of these entities :
/**
* #ORM\Entity
*/
class Contact_Conference_Invitation
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Aurae\UserBundle\Entity\Contact")
*/
private $contact;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Aurae\ConferenceBundle\Entity\Conference")
*/
private $conference;
/**
* #var datetime dateInvitation
*
* #ORM\Column(name="dateInvitation", type="datetime")
*/
private $dateInvitation;
//Getters and setters
}
I have tried updating my sql schema, but the tables corresponding to these entities do not appear. Is there somewhere I have to declare them (config or such)? If not, what's wrong?
Thanks a lot
Edit : I had forgotten the namespace for these class, and that's why they were omitted by Doctrine. Another case closed :) thanks for the answers!
Assumptions ...
No, you don't need to declare them anywhere else than in your Entity directory.
What's the error message you got?
I guess you added
use Doctrine\ORM\Mapping as ORM;
on the top of your classes to let them be mapped.
I tried ...
I tried to generate your entities by adding a simple Contact & Conference entities and it's working fine.
Here are the code snippets:
Contact_Conference_Invitation.php
namespace Ahsio\StackBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Contact_Conference_Invitation
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Ahsio\StackBundle\Entity\Contact")
*/
private $contact;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Ahsio\StackBundle\Entity\Conference")
*/
private $conference;
/**
* #var datetime dateInvitation
*
* #ORM\Column(name="dateInvitation", type="datetime")
*/
private $dateInvitation;
//Getters and setters
}
Contact.php
namespace Ahsio\StackBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Contact
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #param $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Conference.php
namespace Ahsio\StackBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Conference
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #param $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Here are the generated tables:
NB: I used a specific namespace for the entities generation to work fine, you need to change them.
Also don't forget to check that you have automapping enabled.
In your config.yml you should have
doctrine:
orm:
auto_mapping: true
Came across this question because my entities weren't generated as well, this was my issue, it could save some time to people struggling with the same issue.
I don't see the definition of your ManyToMany relation in the sample of code you provided.
As an example, here's a ManyToMany relationship I implemented for a project
Entity Project.php
/**
* #var Provider[]
*
* #ORM\ManyToMany(targetEntity="Provider", mappedBy="projects")
*/
protected $providers = null;
Entity Provider.php
/**
* #var Project[]
*
* #ORM\ManyToMany(targetEntity="Project", inversedBy="providers")
* #ORM\JoinTable(name="PROVIDER_PROJECT")
*/
protected $projects = null;
As you can see, here you define the join table for your ManyToMany relationship.
Of course those entities are specific for my particular project but you get the idea and you can adapt it easily for your needs.

Categories