I have an object with several collection. I saved the data correctly and then, when I do "object->getCollection()", I didn´t obtain the data.
This are my entities:
Persona:
/**
* #ORM\OneToMany(targetEntity="PersonaDomicilio",mappedBy="idPersona",cascade={"persist"},orphanRemoval=true)
*/
public $domicilios;
public function __construct() {
$this->domicilios = new ArrayCollection();
}
public function getDomicilios() {
return $this->domicilios;
}
public function addDomicilio(PersonaDomicilio $persona_domicilio) {
$persona_domicilio->setIdPersona($this);
$this->domicilios[] = $persona_domicilio;
return $this;
}
public function removeDomicilio(PersonaDomicilio $persona_domicilio) {
$this->domicilios->removeElement($persona_domicilio);
}
PersonaDomicilio:
/**
* #var \AppBundle\Entity\Persona
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Persona",inversedBy="domicilios")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_persona", referencedColumnName="id_persona")
* })
*/
protected $idPersona;
The collections are null when I dump persona, and when I dump persona->getDomicilios() too.
Related
I have an intermediate table that acts as a pivot between two others: user, punto_suministro and table pivot user_punto_suministro:
How to fetch data from table user to table punto_suministro?
Entity User:
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
*/
class User implements UserInterface
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
.....
/**
* #ORM\OneToMany(targetEntity=UserPuntoSuministro::class, mappedBy="user")
*/
private $userPuntoSuministros;
/**
* #throws \Exception
*/
public function __construct()
{
$this->puntoSuministros = new ArrayCollection();
$this->userPuntoSuministros = new ArrayCollection();
}
/**
* #return Collection|UserPuntoSuministro[]
*/
public function getUserPuntoSuministros(): Collection
{
return $this->userPuntoSuministros;
}
public function addUserPuntoSuministro(UserPuntoSuministro $userPuntoSuministro): self
{
if (!$this->userPuntoSuministros->contains($userPuntoSuministro)) {
$this->userPuntoSuministros[] = $userPuntoSuministro;
$userPuntoSuministro->setUser($this);
}
return $this;
}
public function removeUserPuntoSuministro(UserPuntoSuministro $userPuntoSuministro): self
{
if ($this->userPuntoSuministros->contains($userPuntoSuministro)) {
$this->userPuntoSuministros->removeElement($userPuntoSuministro);
// set the owning side to null (unless already changed)
if ($userPuntoSuministro->getUser() === $this) {
$userPuntoSuministro->setUser(null);
}
}
return $this;
}
Entity PuntoSuministro:
/**
* #ORM\Entity(repositoryClass=PuntoSuministroRepository::class)
*/
class PuntoSuministro
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
...
/**
* #ORM\OneToMany(targetEntity=UserPuntoSuministro::class, mappedBy="punto_suministro")
*/
private $userPuntoSuministros;
public function __construct()
{
$this->userPuntoSuministros = new ArrayCollection();
}
/**
* #return Collection|UserPuntoSuministro[]
*/
public function getUserPuntoSuministros(): Collection
{
return $this->userPuntoSuministros;
}
public function addUserPuntoSuministro(UserPuntoSuministro $userPuntoSuministro): self
{
if (!$this->userPuntoSuministros->contains($userPuntoSuministro)) {
$this->userPuntoSuministros[] = $userPuntoSuministro;
$userPuntoSuministro->setPuntoSuministro($this);
}
return $this;
}
public function removeUserPuntoSuministro(UserPuntoSuministro $userPuntoSuministro): self
{
if ($this->userPuntoSuministros->contains($userPuntoSuministro)) {
$this->userPuntoSuministros->removeElement($userPuntoSuministro);
// set the owning side to null (unless already changed)
if ($userPuntoSuministro->getPuntoSuministro() === $this) {
$userPuntoSuministro->setPuntoSuministro(null);
}
}
return $this;
}
Entity UserPuntoSuministro (table pivot):
/**
* #ORM\Entity(repositoryClass=UserPuntoSuministroRepository::class)
*/
class UserPuntoSuministro
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="userPuntoSuministros")
*/
private $user;
/**
* #ORM\ManyToOne(targetEntity=PuntoSuministro::class, inversedBy="userPuntoSuministros")
*/
private $punto_suministro;
public function getId(): ?int
{
return $this->id;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getPuntoSuministro(): ?PuntoSuministro
{
return $this->punto_suministro;
}
public function setPuntoSuministro(?PuntoSuministro $punto_suministro): self
{
$this->punto_suministro = $punto_suministro;
return $this;
}
I try and access as follows:
$user = $userRepository->find($this->security->getUser());
$pivote = $user->getUserPuntoSuministros();
but from here I don't know how to recover the punto_suministro of a user to show it on twig.
Thanks in advance.
In simple case you could iterate over $user->getUserPuntoSuministros() and fetch concrete punto_suministro's
$user = $userRepository->find($this->security->getUser());
$puntoSuministros = []; // contains PuntoSuministro's of User
foreach ($user->getUserPuntoSuministros() as $userPuntoSuministro) {
$puntoSuministros[] = $userPuntoSuministro->getPuntoSuministro();
}
I have problem with my symfony code:
My repository update method
/**
* #param MenuModel $menu
* #return MenuEntity|MenuModel
* #throws RepositoryException
*/
public function updateMenu(MenuModel $menu)
{
try {
$transformedMenu = $this->menuTransformer->transform($menu);
$transformedMenu = $this->getEntityManager()->merge($transformedMenu);
$this->getEntityManager()->flush($transformedMenu);
$this->getEntityManager()->detach($transformedMenu);
return $this->menuTransformer->transform($transformedMenu);
} catch (\Exception $e) {
throw new RepositoryException($e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
}
}
My Element entity:
/**
* Element.
*
* #ORM\HasLifecycleCallbacks
* #ORM\Table(name="element")
* #ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
* #ORM\Entity(repositoryClass="CP\API\Repository\ElementRepository")
*/
class Element extends \CP\RestBundle\Model\Element
{
use Traits\SystemObjectTrait;
use Traits\ChannelsTrait;
use Traits\PropertiesTrait;
use Traits\WorkflowTrait;
/**
* #ORM\ManyToOne(targetEntity="Menu", inversedBy="contents")
* #ORM\JoinColumn(name="menu_id", referencedColumnName="id")
*/
protected $menu;
/**
* Element constructor.
*/
public function __construct()
{
parent::__construct();
}
/**
* #param int $id
*
* #return Element
*/
public function setId(int $id): self
{
$this->id = $id;
return $this;
}
/**
* Update publication by modification when empty
* Update status according to publication, unpublication and archiving
*
* #ORM\PrePersist()
*/
protected function prePersist()
{
$this->updatePublication();
$this->updateStatus();
}
/**
* Update publication by modification when empty
* Update status according to publication, unpublication and archiving
*
* #ORM\PreUpdate()
*/
public function preUpdate()
{
$this->updatePublication();
$this->updateStatus();
}
/**
* Increases object version
*/
public function increaseVersion()
{
++$this->version;
}
/**
* #return mixed
*/
public function getMenu()
{
return $this->menu;
}
/**
* #param mixed $menu
*/
public function setMenu($menu): void
{
$this->menu = $menu;
}
}
My Menu entity
<?php
namespace CP\API\Entity;
use CP\API\Entity\Traits\TimestampableTrait;
use CP\Model\Configuration;
use CP\Model\Content;
use CP\Model\Language;
use CP\Model\MenuTranslation;
use CP\RestBundle\Model\Locator;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\HasLifecycleCallbacks()
* #ORM\Table(name="custom_menu")
* #ORM\Entity(repositoryClass="CP\API\Repository\MenuRepository")
*/
class Menu
{
use TimestampableTrait;
/**
* #var int
*
* #ORM\Id()
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="CP\API\Entity\Element",mappedBy="menu",cascade={"persist"})
*/
protected $contents;
public function __construct(Menu $parent = null)
{
$dateTime = new \DateTime();
$this->creation = $dateTime;
$this->modification === null && $this->setModification($dateTime);
$this->contents = new ArrayCollection();
}
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
/**
* #return ArrayCollection
*/
public function getContents(): ArrayCollection
{
return $this->contents;
}
/**
* #param ArrayCollection $contents
*/
public function setContents(ArrayCollection $contents): void
{
$this->contents = $contents;
}
/**
* #param Element $element
* #return $this
*/
public function addContent(Element $element): self
{
if (!$this->contents->contains($element)) {
$this->contents[] = $element;
$element->setMenu($this);
}
return $this;
}
/**
* #param Element $element
* #return $this
*/
public function removeContent(Element $element): self
{
if ($this->contents->contains($element)) {
$this->contents->removeElement($element);
if ($element->getMenu() === $this) {
$element->setMenu(null);
}
}
return $this;
}
}
My menu model
<?php
namespace CP\Model;
use CP\RestBundle\Model\Element;
use CP\RestBundle\Model\Locator;
use CP\RestBundle\Model\Product;
use CP\RestBundle\Model\Traits\TimestampableTrait;
class Menu extends BaseModel
{
/** #var Content[] */
protected $content;
/**
* #return array|null
*/
public function getContent(): ?array
{
return $this->content;
}
/**
* #param Content[] $content
*/
public function setContent(array $content): void
{
$this->content = $content;
}
}
My transformer from model to entity
public function transform($object)
{
if ($object instanceof Menu) {
$menuData = new MenuEntity();
if ($object->getId())
$menuData->setId($object->getId());
if ($object->getContent() instanceof Content) {
$contentEntity = new ContentEntity();
$content = $object->getContent();
$contentEntity->setId($content->getId());
$menuData->addContent($this->attachToEntityManager($contentEntity));
}
return $menuData;
}
private function attachToEntityManager($object)
{
try {
$attachedObject = $this->entityManager->merge($object);
return $attachedObject;
} catch (ORMException $e) {
throw new ModelTransformationException(sprintf('Model transformation error, object could not be attached to Entity Manager: %s in %s',
$e->getMessage(), $e->getFile() . ':' . $e->getLine()));
}
}
When i try saved data then i don't have any error, but on database nothing change i.e. element entity don't have assign menu_id from relation. I don't know what is wrong, maybe i don't know how to use and save OneToMany relation.
Any idea?
Can you give us more context of what your code is doing ? The constructor of MenuEntity is strange, no use of $parent, a boolean comparaison isn't used. Why do you need to use detach and merge methods of entityManager
- Mcsky
Is right, I don't see the point of using detach and/or merge here.
Normally with a OneToMany relationship you use entity manager and persist both relations, flush and you should have an entity with a OneToMany relationship.
I hope this might be helpful, specifically this part: https://symfony.com/doc/current/doctrine/associations.html#saving-related-entities
example:
// relates this product to the category
$product->setCategory($category);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($category);
$entityManager->persist($product);
$entityManager->flush();
I have 2 entities, User and courses, each student can have many courses and each course can have many students. Anyway, I'm trying to make it so that when a user connects to his account, it shows him all the courses he's related to. I know I have to do it from my controller but how do I get only the ones he's related to.
my entities
<?php
/**
* #ORM\Entity
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
public function getId()
{
return $this->id;
}
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Courses", mappedBy="Users")
*/
private $courses;
public function __construct()
{
$this->courses = new ArrayCollection();
}
/**
* #return Collection|course[]
*/
public function getCourses(): Collection
{
return $this->courses;
}
public function addCourse(Course $course): self
{
if (!$this->courses->contains($course)) {
$this->courses[] = $course;
$course->addUser($this);
return $this;
}
return $this;
}
public function removeCourse(Course $course): self
{
if ($this->courses->contains($course)) {
$this->courses->removeElement($course);
$course->removeUser($this);
}
return $this;
}
}
<?php
/**
* #ORM\Entity(repositoryClass="App\Repository\CourseRepository")
*/
class Course
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=55)
*/
private $name;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\user", inversedBy="courses")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getname(): ?string
{
return $this->name;
}
public function setname(string $name): self
{
$this->name = $name;
return $this;
}
/**
* #return Collection|user[]
*/
public function getUser(): Collection
{
return $this->user;
}
public function addUser(user $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
}
return $this;
}
public function removeUser(user $user): self
{
if ($this->users->contains($user)) {
$this->users->removeElement($user);
}
return $this;
}
}
Well, because you apparently have a bi-directional relationship (inversedBy and mappedBy) you dont need to do anything special. Doctrine has already done this. Just grab the user in the controller:
// Once you have a protected controller route,
// you can use $this->getUser() from inside the
// controller action to access the current authenticated user.
$user = $this->getUser();
And iterate as you'd like through their related courses:
foreach ($user->getCourses() as $course) {
}
Because getCourses also returns a Collection instance, you can also use the ->map and ->filter functions that ship with the Collection class...
I am trying to insert into a junction table called post_post_category which is based on Post and PostCategory tables [many to many], i manage to execute the insert but the problem is that when i add a new post it creates a new category.
Post Entity:
class Post
{
...
/**
* #ORM\ManyToMany(targetEntity="PostCategory", cascade={"persist"})
* #ORM\JoinTable(name="post_post_category",
* joinColumns={#ORM\JoinColumn(name="post_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="post_category_id", referencedColumnName="id")}
* )
*/
private $categories;
public function __construct() {
$this->categories = new ArrayCollection();
}
...
public function getCategories(): ?PostCategory
{
return $this->categories;
}
public function addCategory(PostCategory $category): self
{
$this->categories->add($category);
return $this;
}
}
Category Entity:
class PostCategory
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=60)
*/
private $category_description;
public function getId()
{
return $this->id;
}
public function getCategoryDescription(): ?string
{
return $this->category_description;
}
public function setCategoryDescription(string $category_description): self
{
$this->category_description = $category_description;
return $this;
}
}
Controller:
...
$category->setCategoryDescription('New category');
$post->addCategory($category);
$database_manager->persist($post);
$database_manager->flush();
How do i insert an existing category in junction table?
to add an existing category to a Post you will have to retrieve the category from the database
$category = $em->getRepository('AppBundle:PostCategory')->find($categoryId);
$post->addCategory($category);
I hope I can be clear in my question.
In my symfony2 project I'm following this tutorial to make a form in which I can press the link to add as many "auteur" as the user wants, so I tried to do it with form collection.
Everything works fine, except the many to one field that always gets "null" value and not the "id".
Here is what I have done.
Soumission entity in which I have the add "auteur" link
....
/**
* #ORM\OneToMany(targetEntity="tuto\BackofficeBundle\Entity\Auteur",
mappedBy="soumission", cascade={"persist"})
*/
protected $auteurs;
.....
/**
* #param Collection $auteurs
* #return $this
*/
public function setAuteurs(Collection $auteurs)
{
$this->auteurs = $auteurs;
return $this;
}
/**
* Add auteur
*
* #param \tuto\BackofficeBundle\Entity\Auteur $auteur
* #return Soumission
*/
public function addAuteur(Auteur $auteur)
{
if ( ! $this->auteurs->contains($auteur) ) {
$auteur->setSoumission($this); // this should set the "soumission-
id" field
$this->auteurs->add($auteur);
}
return $this->auteurs;
}
public function removeAuteur(Auteur $auteur)
{
if ($this->auteurs->contains($auteur)) {
$this->auteurs->removeElement($auteur);
}
return $this->auteurs;
}
/**
* #return mixed
*/
public function getAuteurs()
{
return $this->auteurs;
}
This is the auteur entity:
/**
* #ORM\ManyToOne(targetEntity="Soumission", inversedBy="auteur")
* #ORM\JoinColumn(name="soumission_id", referencedColumnName="id")
*/
protected $Soumission;
/**
* #param $soumission
* #return $this
*/
public function setSoumission(Soumission $soumission)
{
$this->soumission = $soumission;
return $this;}
/**
* #return mixed
*/
public function getSoumission()
{
return $this->soumission;
}
public function __toString() {
return $this->Soumission;
}
the result should be like the second line and not null value
try to do this :
/**
* #ORM\OneToMany(targetEntity="Auteur",mappedBy="soumission", cascade={"persist"})
*/
protected $auteurs;
/**
* Add auteurs
* #return FormationMsk
*/
public function addAuteur(\tuto\BackofficeBundle\Entity\Auteur $auteurs)
{
$this->auteurs[] = $auteurs;
return $this;
}
/**
* Remove auteurs
*/
public function removeAuteur(\tuto\BackofficeBundle\Entity\Auteur $auteurs)
{
$this->auteurs->removeElement($auteurs);
}
/**
* Get auteurs
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getAuteurs()
{
return $this->auteurs;
}
public function __construct()
{
$this-auteurs = new \Doctrine\Common\Collections\ArrayCollection();
}
and for the auteur entity :
/**
* #ORM\ManyToOne(targetEntity="Soumission", inversedBy="auteurs")
* #ORM\JoinColumn(name="soumission_id", referencedColumnName="id")
*/
protected $soumission;