Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SF2][Symfony2][Symfony] Zapis encji w relacji
Forum PHP.pl > Forum > PHP > Frameworki
damianooo
Czemu ponizszy zapis danych do bazy nie dziala ?

  1. public function createAction(){
  2.  
  3. $type = new Type();
  4. $match = new Match();
  5. $match->getId(3);
  6. $type->setNumberOfPoints(0);
  7. $type->setUser($this->getUser());
  8. $type->setMatch($match);
  9. $em = $this->getDoctrine()->getManager();
  10. $em->persist($type);
  11. $em->flush();
  12.  
  13. }


Blad ktory otrzymyje jest nastepujacy:

  1. A new entity was found through the relationship 'My\TyperkaBundle\Entity\Type#match' that was not configured to cascade persist operations for entity: . To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}).


Relacje miedzy encja Type i Match mam taka:

  1. // Type.php
  2.  
  3. class Type {
  4.  
  5. /**
  6.   * @ORM\ManyToOne(
  7.   * targetEntity = "Match",
  8.   * )
  9.   *
  10.   * @ORM\JoinColumn(
  11.   * name = "match_id",
  12.   * referencedColumnName = "id",
  13.   * onDelete = "SET NULL"
  14.   * )
  15.   */
  16. private $match;

Crozin
Szybkie pytanie: co jest niezrozumiałe w treści wyjątku, który podaje Ci dwa możliwe rozwiązania problemu?
uirapuru
szybka odpowiedz biggrin.gif $em->persist($match) przed flushem powinno pomóc. btw: nie rób tego w kontrolerze.
damianooo
Ok, dodalem:

  1. $em->persist($match);


i udalo sie ... faktycznie nie doczytalem komunikatu, ktory przeciez jasno pisal co trzeba zrobic.

ale nie wiem czemu do bazy nie zostal dodany rekord do tabeli Type o match_id = 3 tylko o match_id = 41 (zainkrementowalo mi match_id )
a wskazalem przeciez w kodzie ze ma zostac dodany rekord z match_id = 3 :



  1. public function createAction(){
  2.  
  3. $type = new Type();
  4. $match = new Match();
  5. $match->getId(3);
  6. $type->setNumberOfPoints(0);
  7. $type->setUser($this->getUser());
  8. $type->setMatch($match);
  9. $em = $this->getDoctrine()->getManager();
  10. $em->persist($match);
  11. $em->persist($type);
  12. $em->flush();
  13. }


kapslokk
  1. $match->getId(3);

get to nie set.

  1. $match->setId(3);

Ale jesli ten match juz istnieje w bazie to chyba powinienes go pobrac
  1. $match = $em->getRepository(...)->findOneById(3)
ohm
Cytat(Crozin @ 23.03.2016, 10:13:40 ) *
Szybkie pytanie: co jest niezrozumiałe w treści wyjątku, który podaje Ci dwa możliwe rozwiązania problemu?

Podpowiadam
Kod
To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}).
damianooo
nie ma takiej metody w mojej encji Match jak setId()
to chyba nie tak sie robi ...

Tak - takie $match o ID = 3 juz istnieje dlatego chcialem pobrac getId()

rozumiem ze musze to zrobic tak:

  1. $match = $em->getRepository(...)->findOneById(3)


i nie ma innej drogi smile.gif

zastanawia mnie tylko dlaczego kolega wczesniej prosil/ostrzegal zeby zapisu nie robic w konrolerze smile.gif ... rozumiem ze chodzi o ograniczenie linii kodu ?
kapslokk
No bo tak jak Ci napisałem, nie powinieneś tego ustawiać ręcznie tylko pobrać z bazy istniejący rekord / zdać się na auto_increment;

getId() jak i cała reszta getterów służy do pobrania wartości z konkretnego obiektu, a nie obiektu z bazy na podstawie tej wartości.

Cytat
zastanawia mnie tylko dlaczego kolega wczesniej prosil/ostrzegal zeby zapisu nie robic w konrolerze smile.gif ... rozumiem ze chodzi o ograniczenie linii kodu ?

Nie mam pojęcia, ktoś mądrzejszy sie musi wypowiedzieć.
Crozin
Cytat
ale nie wiem czemu do bazy nie zostal dodany rekord do tabeli Type o match_id = 3 tylko o match_id = 41 (zainkrementowalo mi match_id )
Zapewne dla właściwości @Id masz ustawione automatyczne generowanie wartości (@GeneratedValue(AUTO)). Wtedy Doctrine zignoruje ręcznie ustawioną wartość przez setId(x).
Cytat
nie ma takiej metody w mojej encji Match jak setId()
to chyba nie tak sie robi ...
Jeżeli decydujesz się na ręczne bądź półautomatyczne (np. przy pomocy sekwencji) nadawanie ID-ków, to taką metodę setId() jak najbardziej możesz czy wręcz musisz mieć. Generalnie nawet jeżeli ID-ki generowane są wyłącznie przez bazę danych metoda setId() wiele nie wadzi, a przy pisaniu testów może się przydać.
Cytat
zastanawia mnie tylko dlaczego kolega wczesniej prosil/ostrzegal zeby zapisu nie robic w konrolerze (IMG:style_emoticons/default/smile.gif) ... rozumiem ze chodzi o ograniczenie linii kodu ?
Liczba linii kodu jest bez znaczenia. Chodzi po prostu o to, że kontroler to nie miejsce dla ORM-a, który raczej powinien być użyty dopiero gdzieś głęboko w warstwie przetwarzania danych, czy właściwie dostępu do danych. Ale nie zawsze potrzebujemy takiej separacji kodu, na różne warstwy stąd Symfony udostępnia "łatwy" dostęp do Doctrine'a wewnątrz kontrolerów dziedziczących po Symfony\Bundle\FrameworkBundle\Controller\Controller.
uirapuru
podpowiem: przypuśćmy, że chcesz dokładnie te samą operację wykonać w symfonowym commandzie. naturalnie, skopiujesz i przekleisz ten kod. co lepsi nawet rejestrują kontroler jako serwis i wywołują te akcje. Ale zawartość akcji Twojego kontrolera jest aplikacją samą w sobie, można jej fragment wydzielić i po prostu użyc: w kontrolerze, w commandzie, a co najwazniejsze - w teście smile.gif

ps. spróbuj przetestować np. jednostkowo te akcje kontrolera.

ps2. bo testujesz, prawda? smile.gif

ps3. przypuścmy sytuację, że pojawia się nowa niekompatybilna wstecz wersja frameworka LUB chcesz zmienić framework. Też kapa przy Twoim podejściu smile.gif

Generalnie: jest wiele powodów, żeby tak nie robić, niewiele powodów by tak robić smile.gif
damianooo
ok dzieki za uwagi ... przemysle to sobie ... chce to robic dobrze wiec bede o tych uwagach pamietal.

Pozdrawiam
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.