Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony][SF2][Symfony2]Problem z encjami
Forum PHP.pl > Forum > PHP > Frameworki
Crash89
Witam,

Pisząc aplikację związaną z książką "Symfony 2 od podstaw", mam taki problem:

Warning: spl_object_hash() expects parameter 1 to be object, null given in D:\xampp\htdocs\Backend5\vendor\doctrine\lib\Doctrine\ORM\UnitOfWork.php line 1977

Problem pojawia się przy każdej próbie wyciągnięcia danych z bazy danych. Jest to projekt przepisany z książki, tak że powinien działać.
Wcześniej w tym projekcie dane były pobierane z bazy bez logowania, ale wszystko było w jednym pakiecie.
Logowanie działa, problem pojawia się gdy próbuję wyświetlic liste kontynentow lub państw.

Poniżej zamieszczę kod Kontrolerów i encji:
Kontynent kontroler:
  1. <?php
  2.  
  3. namespace My\FrontendBundle\Controller;
  4.  
  5. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  6. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  7. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  8. use My\FrontendBundle\Entity\Kontynent;
  9.  
  10. class KontynentController extends Controller
  11. {
  12. /**
  13.   * Lista kontynentow
  14.   *
  15.   * @Route("/kontynenty.html", name="kontynent_index")
  16.   * @Template()
  17.   */
  18. public function indexAction()
  19. {
  20. $em = $this->getDoctrine()->getEntityManager();
  21. $entities = $em->getRepository('MyBackendBundle:Kontynent')->findAll();
  22. return array('entities' => $entities);
  23. }
  24.  
  25. /**
  26.   * Szczegolowe dane kontynentu
  27.   *
  28.   * @Route("/kontynent/{id}.html", name="kontynent_show")
  29.   * @Template()
  30.   */
  31. public function showAction($id)
  32. {
  33. $em = $this->getDoctrine()->getEntityManager();
  34. $entity = $em->getRepository('MyBackendBundle:Kontynent')->find($id);
  35. if (!$entity) {
  36. throw $this->createNotFoundException('Brak kontynentu o podanym id!');
  37. }
  38. return array('entity' => $entity);
  39. }
  40. }

Pnastwo Kontroler:
  1. <?php
  2.  
  3. namespace My\FrontendBundle\Controller;
  4.  
  5. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  6. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  7. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  8. use My\FrontendBundle\Entity\Panstwo;
  9.  
  10. class PanstwoController extends Controller
  11. {
  12. /**
  13.   * Lista wszystkich panstw
  14.   *
  15.   * @Route("/panstwa/html", name="panstwo_index")
  16.   * @Template()
  17.   */
  18. public function indexAction()
  19. {
  20. $em = $this->getDoctrine()->getEntityManager();
  21. $entities = $em->getRepository('MyBackendBundle:Panstwo')->findAll();
  22. return array('entities' => $entities);
  23. }
  24.  
  25. /**
  26.   * Szczegolowe dane panstwa
  27.   *
  28.   * @Route("/panstwo/{id}.html", name="panstwo_show")
  29.   * @Template()
  30.   */
  31. public function showAction($id)
  32. {
  33. $em = $this->getDoctrine()->getEntityManager();
  34. $entity = $em->getRepository('MyBackendBundle:Panstwo')->find($id);
  35. if (!$entity) {
  36. throw $this->createNotFoundException('Brak panstwa o podanym id!');
  37. }
  38. return array('entity' => $entity);
  39. }
  40.  
  41.  
  42. }


Encja Kontynent:
  1. <?php
  2.  
  3. namespace My\BackendBundle\Entity;
  4.  
  5. use Doctrine\ORM\Mapping as ORM;
  6.  
  7. /**
  8.  * My\BackendBundle\Entity\Kontynent
  9.  *
  10.  * @ORM\Table()
  11.  * @ORM\Entity
  12.  */
  13. class Kontynent
  14. {
  15. /**
  16.   * @var integer $id
  17.   *
  18.   * @ORM\Column(name="id", type="integer")
  19.   * @ORM\Id
  20.   * @ORM\GeneratedValue(strategy="AUTO")
  21.   */
  22. private $id;
  23.  
  24. /**
  25.   * @var string $nazwa
  26.   *
  27.   * @ORM\Column(name="nazwa", type="string", length=255)
  28.   */
  29. private $nazwa;
  30.  
  31. /**
  32.   * @ORM\OneToMany(targetEntity="Panstwo", mappedBy="kontynent")
  33.   */
  34. protected $panstwa;
  35.  
  36. /**
  37.   * Get id
  38.   *
  39.   * @return integer
  40.   */
  41. public function getId()
  42. {
  43. return $this->id;
  44. }
  45.  
  46. /**
  47.   * Set nazwa
  48.   *
  49.   * @param string $nazwa
  50.   */
  51. public function setNazwa($nazwa)
  52. {
  53. $this->nazwa = $nazwa;
  54. }
  55.  
  56. /**
  57.   * Get nazwa
  58.   *
  59.   * @return string
  60.   */
  61. public function getNazwa()
  62. {
  63. return $this->nazwa;
  64. }
  65.  
  66. /**
  67.   * Get nazwa
  68.   *
  69.   * @return string
  70.   */
  71. public function __toString()
  72. {
  73. return (string)$this->getNazwa();
  74. }
  75.  
  76. public function __construct()
  77. {
  78. $this->panstwa = new \Doctrine\Common\Collections\ArrayCollection();
  79. }
  80.  
  81.  
  82. /**
  83.   * Add panstwa
  84.   *
  85.   * @param My\BackendBundle\Entity\Panstwo $panstwa
  86.   */
  87. public function addPanstwo(\My\BackendBundle\Entity\Panstwo $panstwa)
  88. {
  89. $this->panstwa[] = $panstwa;
  90. }
  91.  
  92. /**
  93.   * Get panstwa
  94.   *
  95.   * @return Doctrine\Common\Collections\Collection
  96.   */
  97. public function getPanstwa()
  98. {
  99. return $this->panstwa;
  100. }
  101. }


  1. <?php
  2.  
  3. namespace My\BackendBundle\Entity;
  4.  
  5. use Doctrine\ORM\Mapping as ORM;
  6.  
  7. /**
  8.  * My\BackendBundle\Entity\Panstwo
  9.  *
  10.  * @ORM\Table()
  11.  * @ORM\Entity
  12.  */
  13. class Panstwo
  14. {
  15. /**
  16.   * @var integer $id
  17.   *
  18.   * @ORM\Column(name="id", type="integer")
  19.   * @ORM\Id
  20.   * @ORM\GeneratedValue(strategy="AUTO")
  21.   */
  22. private $id;
  23.  
  24. /**
  25.   * @var string $nazwa
  26.   *
  27.   * @ORM\Column(name="nazwa", type="string", length=255)
  28.   */
  29. private $nazwa;
  30.  
  31. /**
  32.   * @ORM\ManyToOne(targetEntity="Kontynent", inversedBy="panstwa")
  33.   */
  34. protected $kontynent;
  35.  
  36. /**
  37.   * Get id
  38.   *
  39.   * @return integer
  40.   */
  41. public function getId()
  42. {
  43. return $this->id;
  44. }
  45.  
  46. /**
  47.   * Set nazwa
  48.   *
  49.   * @param string $nazwa
  50.   */
  51. public function setNazwa($nazwa)
  52. {
  53. $this->nazwa = $nazwa;
  54. }
  55.  
  56. /**
  57.   * Get nazwa
  58.   *
  59.   * @return string
  60.   */
  61. public function getNazwa()
  62. {
  63. return $this->nazwa;
  64. }
  65.  
  66. /**
  67.   * Get nazwa
  68.   *
  69.   * @return string
  70.   */
  71. public function __toString()
  72. {
  73. return $this->getNazwa();
  74. }
  75.  
  76.  
  77. /**
  78.   * Set kontynent
  79.   *
  80.   * @param My\BackendBundle\Entity\Kontynent $kontynent
  81.   */
  82. public function setKontynent(\My\BackendBundle\Entity\Kontynent $kontynent)
  83. {
  84. $this->kontynent = $kontynent;
  85. }
  86.  
  87. /**
  88.   * Get kontynent
  89.   *
  90.   * @return My\BackendBundle\Entity\Kontynent
  91.   */
  92. public function getKontynent()
  93. {
  94. return $this->kontynent;
  95. }
  96. }


Projekt jest podzielony na 3 pakiety, FrontendBundle, BackendBundle i UserBundle.
W jednym z nich są kontrolery wygenerowane dla Panstwa i kontynentu przez panel CRUD.
Więc w aplikacji są po dwa kontrolery dla państwa i Kontynentu ale w różnych pakietach.
prz3kus
Wejdz tu http://symfony.com/doc/current/book/doctrine.html
i poczytaj o Relationship Mapping Metadata w szczególnośći ManyToOne
Crash89
Cytat(prz3kus @ 2.06.2015, 15:11:15 ) *
Wejdz tu http://symfony.com/doc/current/book/doctrine.html
i poczytaj o Relationship Mapping Metadata w szczególnośći ManyToOne


to według dokumentacji jest wszystko dobrze.
Kontynent ma tablice a państwo ma jedną zmienną.
Adnotacje też są dobrze wpisane.
Forti
Pokaż jak dodajesz rekordy. W jaki sposób.
prz3kus
Dziwne moim zdaniem ten zapis
  1. /**
  2.   * @ORM\ManyToOne(targetEntity="Kontynent", inversedBy="panstwa")
  3.   */
  4. protected $kontynent;

troszkę się różni od tego w dokumentacji
  1. /**
  2.   * @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
  3.   * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
  4.   */
  5. protected $category;

Crash89
To nic nie zmienia.
Z tym czy bez tego mam ten sam problem.
Może moja wersja php jest niekompatybilna? (mam wersje 5.6.8)
Działam na wersji Symfony 2.0.10
Już miałem jeden problem z wersją php.
Forti
Cytat(Forti @ 3.06.2015, 13:11:23 ) *
Pokaż jak dodajesz rekordy. W jaki sposób.



Pokaż kod inaczej nie mam jak ci pokazać co robisz źle.


I popraw:

  1. /**
  2.   * @ORM\ManyToOne(targetEntity="Kontynent", inversedBy="panstwa")
  3.   * @ORM\JoinColumn(name="kontynent", referencedColumnName="id")
  4.   */
  5. protected $kontynent;


  1. /**
  2.   * @ORM\OneToMany(targetEntity="Panstwo", mappedBy="kontynent")
  3.   */
  4. protected $panstwa;



to jest źle:

  1. public function addPanstwo(...)


Jeżeli rekord nazywa się Panstwa to setter ma być addPanstwa(Panstwa $panstwa). Zacznij korzystac z angielskich nazw.
prz3kus
Ja Ci proponuje pobrać nowszą wersję Symfony najlepiej od 2.3 w górę (od wersji 2.1 pozmieniała sie kolosalna ilość rzeczy)

edit:
tylko wtedy trzba czytac dokumentacjie online nie książke która kłamie, już od miesiąca po wydaniu smile.gif
Crash89
Rekordy dodaje tak poprzez DataFixtures:
  1. namespace My\FrontendBundle\DataFixtures\ORM;
  2.  
  3. use Doctrine\Common\DataFixtures\FixtureInterface;
  4. use My\BackendBundle\Entity\Kontynent;
  5. use My\BackendBundle\Entity\Panstwo;
  6. use Doctrine\Common\Persistence\ObjectManager;
  7.  
  8. class LoadData implements FixtureInterface
  9. {
  10. function load(ObjectManager $manager)
  11. {
  12. $xml = simplexml_load_file('data/kontynenty.xml');
  13. foreach ($xml->kontynent as $kontynent) {
  14.  
  15. $Kontynent = new Kontynent();
  16. $Kontynent->setNazwa($kontynent->nazwa);
  17. $manager->persist($Kontynent);
  18.  
  19.  
  20. foreach ($kontynent->panstwa->panstwo as $panstwo) {
  21. $Panstwo = new Panstwo();
  22. $Panstwo->setNazwa($panstwo->nazwa);
  23. $Panstwo->setKontynent($Kontynent);
  24. $manager->persist($Panstwo);
  25. }
  26.  
  27. }
  28. $manager->flush();
  29.  
  30. }
  31. }



Jeśli trzeba dodam też kontrolery wygenerowane przez crud, może tam jest problem?
Wcześniejsze pliki poprawiłem i nic to nie zmienia.

Cytat(prz3kus @ 3.06.2015, 13:49:42 ) *
Ja Ci proponuje pobrać nowszą wersję Symfony najlepiej od 2.3 w górę (od wersji 2.1 pozmieniała sie kolosalna ilość rzeczy)

edit:
tylko wtedy trzba czytac dokumentacjie online nie książke która kłamie, już od miesiąca po wydaniu smile.gif


Książkę właściwie skończyłem, fajnie są opisane podstawy a i tak będę musiał przejść na nowszą wersje.
Chcę tylko znaleźć rozwiązanie tego problemu, tak na przyszłość.
Forti
Popraw to co Ci napisałem i powinno działać moim zdaniem.
Crash89
Cytat(Forti @ 3.06.2015, 14:33:37 ) *
Popraw to co Ci napisałem i powinno działać moim zdaniem.


Pozmieniałem i dalej wyświetla mi ten sam błąd.
prz3kus
Dodaj tylko rekord do tabeli kontynent i zobacz czy Ci zadziala

  1. Kontynent = new Kontynent();
  2. $Kontynent->setNazwa($kontynent->nazwa);
  3. $manager->persist("test");
  4. $manager->flush();

Wywal wszytkie petle itp.
Crash89
Dodawanie danych przez doctrine:fixtures:load działa bez problemu, ale przy pobieraniu danych wyrzuca błąd.
Forti
wywal to i przejdź na nową wersje. Sporo rzeczy się zmieniło a nie chce mi się zaglądać do dokumentacji z przed kilku lat aby sprawdzić czy dobrze robisz...

Czyli co zrób:

- Zmień wersje symfony na nową (najlepiej nowa instalacja - ucz się na najnowszych tabilnych wersjach..! zawsze!)
- zacznij używać ANGIELSKICH nazw. Nie polskich...
prz3kus
A gdzie ty w tym kodzie pobierasz dane z bazy bo ja tego nie widzę? Widzę że starasz się pobrać z pliku xml
Crash89
Ta aplikacja jest to przykład ze strony heliona do książki, nic w nia prawie nie ingerowałem.
Jednak chciałem ten problem rozwiązać, gdyż przy googlowaniu znalazłem wiele podobnych problemów.
Dziękuję wam za próbę pomocy i skorzystam z waszych rad, żeby się zabrać za najnowszą wersje, bo sporo rzeczy już nie działa, a to z powodu braku kompatybilności z moja wersją PHP, czy wyżej opisany problem.

Cytat(prz3kus @ 3.06.2015, 15:47:09 ) *
A gdzie ty w tym kodzie pobierasz dane z bazy bo ja tego nie widzę? Widzę że starasz się pobrać z pliku xml


Wyciąganie danych z bazy jest w kontrolerach z pierwszego postu.
A dane z xmla są pobieranie, żeby je potem zapisać w bazie danych.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.