How to use doctrine One-To-Many, Bidirectional? - php

I am making blog maker in symfony and doctrine
I am trying to connect, ID of row in blog posts with comments by blog_id value, but I getting this error
\Entity\BlogPosts.php
The association App\Entity\BlogPosts#comments refers to the owning side field App\Entity\Frontend\Blog\Fe_blog_comments#blogId which is not defined as association, but as field.
The association App\Entity\BlogPosts#comments refers to the owning side field App\Entity\Frontend\Blog\Fe_blog_comments#blogId which does not exist.
My actual code looks like this
\Entity\BlogPosts.php
class BlogPosts
{
/**
* #ORM\OneToMany(targetEntity="App\Entity\Frontend\Blog\Fe_blog_comments", mappedBy="blogId")
*/
private $comments;
//...
}
\Entity\Frontend\Blog\Fe_blog_comments.php
class Fe_blog_comments
{
//...
/**
* #ORM\Column(type="integer")
* #ORM\ManyToOne(targetEntity="App\Entity\BlogPosts", inversedBy="comments")
* #ORM\JoinColumn(name="blog_id", referencedColumnName="id")
*/
private $blogId;
//...
}

Remove #ORM\Column(type="integer"), the column should be managed by #ORM\JoinColumn(name="blog_id", referencedColumnName="id")

Related

Commit order issue when using OneToMany and ManyToOne relations on single inheritance table in Doctrine2

So I have a following single inheritance table defined:
/**
* #Entity
* #Table(name="listKeys")
* #InheritanceType("SINGLE_TABLE");
* #DiscriminatorColumn(name="parent", type="string")
* #DiscriminatorMap({"Type1" = "Something1", "Type2" = "Something2"})
*/
abstract class ListKey
{
/**
* #OneToMany(targetEntity="KeyListValue", mappedBy="listKey", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private Collection $listValues;
/**
* #ManyToOne(targetEntity="KeyListValue")
* #JoinColumn(name="defaultKeyListValueId")
*/
private ?KeyListValue $defaultKeyListValue = null;
}
With the list options defined as:
/**
* #Entity
* #Table(name="keyListValues")
*/
class KeyListValue
{
/**
* #Column(type="string")
*/
private $label;
/**
* #ManyToOne(targetEntity="ListKey", inversedBy="listValues", cascade={"persist"})
* #JoinColumn(name="caKeyId")
*/
private ListKey $listKey;
}
Before adding list values to a key, persisting and flushing worked ok, so the key would get inserted first after the commit order calculation. But once I added a new column default key list value, the commit order changes, and key list values try to get inserted first so the transaction fails.
Workaround is that I use flush() after creating new key and the adding the list values but this is problematic since ListKey also has association with some other entities which are not persisted yet at the time of flush so cascades would have to be declared and I don't want that. Any suggestion on how I can redefine this relationship better or a better workaround so the commit order would first insert keys?

Symfony/Doctrine ManyToMany in the order the are assigned

I have an entity called Game which has a ManyToMany connection with a JoinTable to an entity called Question
This works pretty well. The problem is, that I need the questions in the exact order as they are chosen, not sorted by question id, as I get them now when I call getQuestions() on the Game class.
Is there a way to do that?
The Questions are all added with $game->addQuestion($question);. The Questions are existing, the game is persisted, after the questions are added.
...
class Game {
...
/**
* #ORM\ManyToMany(targetEntity="Question")
* #ORM\JoinTable(name="Games_to_Questions",
* joinColumns={#ORM\JoinColumn(name="game_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="question_id", referencedColumnName="id")}
* )
**/
private $questions;
...
}
...
class Question {
...
}
...
you're going to have to add an intermediary entity with a sort order column. Let's call it GameQuestion.
/**
* #ORM\Table(name="game_question")
* #ORM\Entity(repositoryClass="Gedmo\Sortable\Entity\Repository\SortableRepository")
*/
class GameQuestion {
private $game;
private $question;
/**
* #Gedmo\SortablePosition
*/
private $sortOrder;
}

symfony2 doctrine manytoone relationship

I believe it's that there must be a simple solution for my issue but I can't get that to work and I'm not sure why.
Scenario:
I've got 2 entities: Bike and Review, relationship is OneToMany:
/**
* Bike
*
* #ORM\Entity(repositoryClass="BikeRepository")
* #ORM\HasLifecycleCallbacks
* #ORM\Table(name="bike")
*/
class Bike
{
...
/**
* #var string
*
* #ORM\OneToMany(targetEntity="Review", mappedBy="bike", cascade={"persist"}, fetch="EXTRA_LAZY")
*/
private $reviews;
...
}
/**
* Review
*
* #ORM\Entity(repositoryClass="ReviewRepository")
* #ORM\Table(name="review")
* #ORM\HasLifecycleCallbacks()
*/
class Review
{
...
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="Bike", inversedBy="reviews", fetch="EXTRA_LAZY")
* #ORM\JoinColumn(name="bike_id", referencedColumnName="id")
*/
private $bike;
....
}
Getters and setters has been generated by doctrine.
On the frontend I've got a form where bike is as a hidden field because there is an autocomplete field with ajax request. So in the controller if $form->isValid() I'm getting bike id from the hidden field, search database for that bike and set bike as below:
if ($form->isValid()) {
if ($bikeId) {
$bike = $this->em->getRepository('BikeBundle:Bike')->findOneBy(array('id' => $bikeId));
$review->setBike($bike);
}
$this->em->persist($review);
$this->em->flush();
}
And this is always giving me NULL in the database for bike_id. Any idea what could be wrong? I have tried to dump $review before persist and I can get the bike details so I don't know what's going wrong. In the entity setBike() method I can get any value of that Bike object except getId() is returning NULL.
Thanks for any help.
you don't need to persist an existing entity, so you can just save your entity like
$review->setBike($bike);
$this->em->flush();
try to check if doctrine really returns any entities..I'm afraid if it doesn't return Bike entity
UPD: Also try to check the namespace of Bike Entity class. It seems like it is wrong in your case, because usually it looks like "AcmeBikeBundle:Bike"

Accessing relations of a table with inheritance

I have an Inheritance class as shown here:
As you can easily see users, buildings and hotels have addresses (more than one) and address table keeps the id of the owner in whose column.
Is my logic correct?
Let's say I want to get the address of user (or buildings or hotels) whose id is 2; must I run a DQL statement (and how?) or can I get it with find() function without DQL?
And I'll be happy if you give example since Doctrine documentation doesn't help much.
Thanks.
Edit: users, buildings and hotels are just symbolic names that is why they can have multiple addresses otherwise buildings and hotels would have only one address.
Edit 2:I think I couldn't make myself clear, when I talk about the Class Table Inheritance I mean entity class has the Discriminator column as
/**
* ...
*
* #DiscriminatorColumn(name="classname", type="string")
* #DiscriminatorMap({"Entities\users" = "Entities\users",
* "Entities\buildings" = "Entities\buildings"}) ... etc
*/
Each and every subclass is related to parent (Entity) with the foreign key relation as "id". But of course doctrine creates this relation already for me.
Usually an Address is a typical value object. Value objects are usually stored with the entity compositing the value object so it is neither about relations nor about class table inheritance. If your domain indicates otherwise (e.g. you can do something with your address, meaning), they might be an entity, than entity Hotel holds an entity Address (persisted in a n:m relation table) and entity Building holds and Address too (in a different n:m relation table).
If you go the value object route, things are different. You would store the address with the Building entity as well as with the Hotel entity (as you would do it with other value objects may it be Moneyor Email or Password). So you don’t need relations at all, just a few more fields. The issue with Doctrine 2 is, that it does not support Component mapping. Component mapping would be used to nicely store value objects. T accomplish the same thing with Doctrine 2, you would implement a #prePersist and a #postLoad handler like that:
class Hotel
{
private ;
/** These fields are persisted */
/** #Column(type=string) */
private $addressStreet;
/** #Column(type=string) */
private $addressCity;
/** #Column(type=string) */
private $addressZip;
/** #Column(type=string) */
private $addressCountry;
/** #prePersist */
public function serializeValueObjects()
{
$this->addressStreet = ->address->getStreet();
$this->addressCity = ->address->getCity();
$this->addressZip = ->address->getZip();
$this->addressCountry = ->address->getCountry();
}
public function unserializeValueObjects()
{
$this->address = new Address(->addressStreet, ->addressCity, ->addressZip, ->addressCountry);
}
}
As you need to serialize/unserialize Address value objects in various places, you might want to extract the serializing code into a separated class.
/**
*
* #Entity
* #Table(name="proposaltemplate")
* #InheritanceType("JOINED")
* #DiscriminatorColumn(name="entitytype", type="string")
* #DiscriminatorMap({"proposal" = "ProposalTemplate","page" = "PageTemplate"})
*
*/
abstract class AbstractProposalTemplate
{
/**
*
* #var integer
* #Id
* #Column(type="integer")
* #generatedValue(strategy="AUTO")
*
*/
private $id;
}
next
#Entity
class ProposalTemplate extends AbstractProposalTemplate
{
#Id
#Column(type="integer")
#generatedValue(strategy="AUTO")
private $id;
}
next another class
#Entity
class PageTemplate extends AbstractProposalTemplate
{
/**
*
* #var integer
* #Id
* #Column(type="integer")
* #generatedValue(strategy="AUTO")
*
*/
private $id;
}
So you've got a superclass called "Entity", which has subclasses "User", "Building", and "Hotel".
Your "Entity" entity should have a OneToMany relation to Address. Let's imagine it looks like this, in your Entity definition:
/**
* #OneToMany(targetEntity="Address", mappedBy="whose"
*/
protected $addresses;
This is a more-or-less fine approach, though the use of inheritance is a little smelly.
Then if you want to iterate over the addresses, from inside User, Building, or Hotel:
foreach($this->addresses as $address){
//do something with adderess
}
Does that answer your question?

Many To Many Mapping Issue

I'm currently trying to map music related data using Doctrine2's POPO Annotations.
I haven't had problems mapping any other many-to-many relations, but one specific relation is giving me trouble. It does not throw an error, but the mapping does not get inserted into the mapping table (artist_album)
Artist:
<?php
/**
* #orm:Entity
* #orm:Table(name="artist")
*/
class Artist
{
...
/**
* #orm:ManyToMany(targetEntity="Company\MusicBundle\Entity\Album", inversedBy="artists", cascade={"persist"})
* #orm:JoinTable(name="artist_album",
* joinColumns={#orm:JoinColumn(name="artist_id", referencedColumnName="id")},
* inverseJoinColumns={#orm:JoinColumn(name="album_id", referencedColumnName="id")})
*
* #var ArrayCollection
*/
private $albums;
...
}
Album
....
/**
* #orm:ManyToMany(targetEntity="Company\MusicBundle\Entity\Artist", mappedBy="albums", cascade={"persist"})
*
* #var ArrayCollection
*/
private $artists;
...
}
I'm sure it's just something in I've done wrong in the mapping, but I just can't put my proverbial finger on it.
My problem was that I was setting the artist on the inverse side of the relationship. It appears you must set the relationship on the owning side (in this case, Artist).

Categories