Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Frameworki _ [SF2][Symfony2][Symfony] Zapis encji w relacji

Napisany przez: damianooo 23.03.2016, 09:24:15

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;


Napisany przez: 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?

Napisany przez: uirapuru 23.03.2016, 10:41:06

szybka odpowiedz biggrin.gif $em->persist($match) przed flushem powinno pomóc. btw: nie rób tego w kontrolerze.

Napisany przez: damianooo 23.03.2016, 11:39:34

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



Napisany przez: kapslokk 23.03.2016, 11:48:01

  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)

Napisany przez: ohm 23.03.2016, 11:49:32

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"}).

Napisany przez: damianooo 23.03.2016, 11:51:37

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 ?

Napisany przez: kapslokk 23.03.2016, 12:00:43

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

Napisany przez: Crozin 23.03.2016, 12:54:26

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.

Napisany przez: uirapuru 23.03.2016, 13:19:09

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

Napisany przez: damianooo 23.03.2016, 13:43:19

ok dzieki za uwagi ... przemysle to sobie ... chce to robic dobrze wiec bede o tych uwagach pamietal.

Pozdrawiam

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)