Doctrine OneToMany, nie usuwa rekordu z bazy

0

Cześć,
Mam mały problem z usuwaniem relacji OneToMany, Mam 2 encje
MenuItemTranslation

    /**
     * @ORM\Entity()
     * @ORM\Table(name="custom_menu_item_translation")
     */
            class MenuItemTranslation 
            {
               use Traits\UniqueIdTrait;
            /**
             * @ORM\ManyToOne(targetEntity="MenuItem", inversedBy="translations")
             * @ORM\JoinColumn(name="menu_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
             */
            protected MenuItem $menu;
        
            /**
             * @return MenuItem
             */
            public function getMenu(): MenuItem
            {
                return $this->menu;
            }
        
            /**
             * @param MenuItem $menu
             *
             * @return MenuTranslation
             */
            public function setMenu(MenuItem $menu): self
            {
                $this->menu = $menu;
                return $this;
            }
        }

MenuItem

  <?php
   
   /**
    * @ORM\HasLifecycleCallbacks()
    * @ORM\Table(name="custom_menu_items")
    * @ORM\Entity(repositoryClass="WebApi\API\Repository\MenuItemRepository")
    */
   class MenuItem
   {
       /**
        * @var Collection|MenuItemTranslation[]
        *
        * @ORM\OneToMany(targetEntity="MenuItemTranslation", cascade={"persist","remove"}, orphanRemoval=true, mappedBy="menu")
        */
       protected ?Collection $translations = null;
   
       public function __construct()
       {
           $this->translations = new ArrayCollection();
       }
  
       /**
        * @return MenuItemTranslation[]|Collection
        */
       public function getTranslations()
       {
           return $this->translations;
       }
   
       /**
        * @param MenuItemTranslation $translation
        * @return $this
        */
       public function addTranslation(MenuItemTranslation $translation): self
       {
           if (!$this->translations->contains($translation)) {
               $this->translations[] = $translation;
           }
   
           return $this;
       }
   
       /**
        * @param MenuItemTranslation $translation
        * @return $this
        */
       public function removeTranslation(MenuItemTranslation $translation): self
       {
           if ($this->translations->contains($translation)) {
               $this->translations->removeElement($translation);
           }
   
           return $this;
       }
   
   }

Metoda do usuwania translacji z menu

  public function removeMenuItemTranslation(MenuItemTranslation $menuItemTranslation, MenuItem $menuItem)
   {
       $menuItemTranslations = $menuItem->getTranslations();
   
       unset($menuItemTranslations[array_key_first([$menuItemTranslation])]);
       $menuItem->setTranslations($menuItemTranslations);
       return $this->menuItemRespository->updateMenuItem($menuItem);
   }

metoda do aktualizacji MenuItem

    public function updateMenuItem(MenuItemModel $menuItem): ?MenuItemModel
    {
        try {
            $transformedMenu = $this->menuItemTransformer->transform($menuItem);
            $transformedMenuItem = $this->getEntityManager()->merge($transformedMenu);
    
            $this->getEntityManager()->flush($transformedMenuItem);
            $this->getEntityManager()->detach($transformedMenuItem);
    
            return $this->menuItemTransformer->transform($transformedMenuItem);
        } catch (Exception $e) {
            throw new RepositoryException($e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
        }
    }

I teraz tak, mam MenuItem który ma przypisane 2 translacje, jedną z nich usuwam. I w poniższych linijkach pozakuje mi MenuItem z jednym językiem, tym który chcę zostawić

    $transformedMenu = $this->menuItemTransformer->transform($menuItem);
    $transformedMenuItem = $this->getEntityManager()->merge($transformedMenu);

Natomiast linijkę niżej tzn

    $this->getEntityManager()->flush($transformedMenuItem);

pokazuje mi znowu 2 tłumaczenia, to które chce zostawić i usunąć. Podczas aktualizacji, nie pokazuje mi żadnego błędu, ale też nie usuwa rekordu z bazy. Ktoś ma jakiś pomysł? Cały kod umieściłem powyżej.

Testuję w taki sposób

$menuItem = $this->menuService->getMenuItem($id);
    $menuItemTranslation = $this->menuService->getMenuItemTranslation(2, $menuItem);
    $menuItem->removeTranslation($menuItemTranslation);
    $this->menuService->updateMenuItem($menuItem);

Nie ważne, czy użyję z entity removeTranslation czy z serwisu removeMenuItemTranslation, efekt jest ten sam tzn brak błędu i nie usuwa rekordy.
Jakieś pomysły? Bo mi już ich zabrakło.

1

dlaczego do usuwania nie używasz
public function removeTranslation(MenuItemTranslation $translation): self

0

@Miang: Cześć :) Bo to nie działa, w ogóle nie usuwa rekordu z bazy. Nie mogę edytować moje posta to dodam tutaj kod. MOja relacja wygląda tak:
MenuItem

    /**
     * @var Collection|MenuItemTranslation[]
     *
     * @ORM\OneToMany(targetEntity="MenuItemTranslation", cascade={"persist", "merge", "detach", "refresh","remove"}, orphanRemoval=true, mappedBy="menu")
     */
    protected ?Collection $translations = null;

MenuItem translation

    /**
     * @ORM\ManyToOne(targetEntity="MenuItem", inversedBy="translations")
     * @ORM\JoinColumn(name="menu_id", referencedColumnName="id", nullable=false)
     */
    protected MenuItem $menu;

I teraz problem jest taki, że mogę dodawać, usuwać i edytować, ale mogę dodać tylko jeden MenuItemTranslation, dla MenuItem, jak chcę dodać kolejny to dostaję błąd:

A managed+dirty entity                                                 
         WebApi\API\Entity\MenuItemTranslation@000000000f6037cd000000004b
         e67e2f can not be scheduled for insertion. in             

I nie wiem o co mu chodzi. Update itemu wygląda tak

  public function updateMenuItem(MenuItemModel $menuItem): ?MenuItemModel
    {
        try {
            $transformedMenu = $this->menuItemTransformer->transform($menuItem);
            $transformedMenu = $this->getEntityManager()->merge($transformedMenu);

            $this->getEntityManager()->flush($transformedMenu);
            $this->getEntityManager()->detach($transformedMenu);

            return $this->menuItemTransformer->transform($transformedMenu);
        } catch (Exception $e) {
            throw new RepositoryException($e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
        }
    }

I do tej metody leci MenuItem z dodanym nowym MenuItemTranslation. I jak np w MenuItemTranslation dodam cascade={"all"} to działa dodawanie oraz usuwanie, ale edycja już nie tzn nie dostaje błędu, ale też nie robi update rekordu.

Nie wygląda mi to na problem z relacją.

1

a masz całość gdzieś na githubie?

0

Nie, to projekt w pracy :/ Sam update MenuItem działa bez problemu, jak chcę dodać translację to doda, ale jak chcę dodać kolejną to już błąd. Tutaj używają transformacji z Model na Entity i z Entity na Model, może gdzieś tutaj jest problem z transformacją translacji, ale w takim wypadku nie dodałoby nawet jednej.

1

czyli jakaś radosna twórczość kolegów w pracy, trudno stwierdzić co namieszali. aniew ma jkiś wyciszonych błedów sql? może w logu serwera?

2

@Miang: znalazłem problem, oczywiście jest on w ich wynalazku :D Jak pominąłem ich wynalazek, to wszystko działa bez problemu, niestety mają wymóg, że musi z tym działać, więc nie zostaje mi nic innego jak naprawa ich zabawki :D

0

@Miang: Problem jest taki, że mogę dodać MenuItemTranslation do MenuItem, jednak jak chcę dodać drugą translację, gdzie zmienia się np samo name to dostaję błąd:

 [ERROR] A managed+dirty entity                                                 
         WebApi\API\Entity\MenuItemTranslation@00000000455c15a7000000002e
         978bc9 can not be scheduled for insertion.           

I już 3 dzień nad tym siedzę, bez użycia transformatora wszystko chodzi super, niestety musi być translacja z Entity na Model

1 użytkowników online, w tym zalogowanych: 0, gości: 1