Doctrine 2 / Kdyby Doctrine – nefunkční asociace

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
serten
Člen | 55
+
0
-

Zdravím,

Mám celkem zapeklitej problém a už několik dní se mi ho nedaří vyřešit. Mám dvě entity, mezi kterými je vztah OneToMany a ManyToOne. Zde je implementace důležitých atributů:

/**
* @ORM\Entity
* @ORM\Table(name="header_fotos")
*/

class HeaderFoto extends BaseEntity{

    ....

    /**
     *
     * @ORM\Column(type="integer")
     * @ORM\ManyToOne(targetEntity="\App\Webpage\Webpage", inversedBy="headerFotos")
     * @ORM\JoinColumn(name="webpage_id", referencedColumnName="id")
     */
    protected $webpage;

    ...
}


/**
 * @ORM\Entity
 * @ORM\Table(name="webpages")
 */
class Webpage extends BaseEntity{
    ...

    /**
     * @ORM\OneToMany(targetEntity="\App\Webpage\HeaderFoto", mappedBy="webpage")
     */
    protected $headerFotos;

    public function __construct() {
        parent::__construct();

        $this->headerFotos = new ArrayCollection();
   }
}

Vím jistě, že anotace mapování je správně, bylo mi to potvrzeno z několika zdrojů. Problémem je ale to, že když si vytáhnu z databáze objekt typu Webpage a potom si chci vypsat všechny související objekty typu HeaderFoto, tak nastane problém. Z nějakého důvodu Doctrina nemá vytvořenou asociaci a vyhazuje mi to chybu. Konkrétně v souboru \Doctrine\ORM\Persisters\BasicEntityPersister.php v metodě getOneToManyStatement. Snaží se to získat související objekty, které by měly být předpokládám lazy loadingem natažený z databáze, ale pole **associationMappings **je prázdný.

Dostal jsem ještě radu zkusit to přepsat pro jistotu na vztah typu OneToOne, ale nastal stejný problém. Vyhodilo mi to exceptionu No mapping found for field webpage.

Pomocí composeru jsem si stáhnul nejnovější verzi Kdyby/Doctrine, se kterou se společně stáhla i Doctrina.

Díky za jakoukoliv pomoc.

David Matějka
Moderator | 6445
+
+1
-

V tom mapovani u HeaderFoto::webpage nema co delat to @ORM\Column

serten
Člen | 55
+
0
-

Odstranění tohoto řádku bohužel nepomůže.

Azathoth
Člen | 495
+
0
-

a updatoval jsi schéma databáze po ostranění toho řádku? promazal jsi cache před tím updatem schématu?

serten
Člen | 55
+
0
-

Ano, cache jsem pokaždé promazal. Po odstranění toho řádku se schéma právě vůbec nezměnilo.

Azathoth
Člen | 495
+
0
-

a jak vypadá schéma? jsou ty tabulky v databázi správně?

Tomáš Votruba
Moderator | 1114
+
+1
-

Taky bych zkusil validaci mappingu v cli.

php www/index.php orm:validate-schema
serten
Člen | 55
+
0
-

Super rada, tohle to už někam posouvá. Vyhodilo mi to následující hlášku:

[Mapping] FAIL – The entity-class ‚App\Webpage\Webpage‘ mapping is invalid:

  • The association App\Webpage\Webpage#headerFotos refers to the owning side field App\Webpage\HeaderFoto#webpage which is not defined as association, but as field.
  • The association App\Webpage\Webpage#headerFotos refers to the owning side field App\Webpage\HeaderFoto#webpage which does not exist.

[Database] OK – The database schema is in sync with the mapping files.

Nenapadá vás jak to opravit? Protože vše mám podle dokumentace napsané jak jsem už ukázal v prvním příspěvku.

Azathoth
Člen | 495
+
0
-

možnázkusit odstranit ten joinColumn

serten
Člen | 55
+
0
-

To jsem právě kdysi zkoušel taky a nepomohlo to. Navíc nepřijde mi, že by to mělo nějak ovlivnit, když je takhle položka optional. Nebude tam třeba problém s inicializací toho ArrayCollection?

Tharos
Člen | 1030
+
0
-

@serten: Ta chybová hláška odpovídá mapování, ve kterém máš nad HeaderFoto::$webpage stále ještě anotaci @ORM\Column (což je přesně chybně v tom Tvém prvním příspěvku). To znamená, že Ti skutečně ještě někde v cache visí. :) Anotaci @ORM\JoinColumn používáš správně.

Takže zkus fakt ještě jednou promazat všechny cache a pro jistotu taky zkus znovu vygenerovat proxy třídy přes command orm:generate-proxies. To by bylo, aby to nezabralo. :)

serten
Člen | 55
+
0
-

Ok, jak se k tomu dostanu, tak to zkusím :-) Jinak je možné, že Doctrina má někde svou vlastní cache kromě adresáře temp/cache?

Tharos
Člen | 1030
+
0
-

No to záleží. :)

Doctrine obecně umí cachovat řadu věcí a snad všechny jdou nakonfigurovat přes tu Kdyby extenzi: https://github.com/…xtension.php#… (takhle cca to pak ta extenze deleguje Doktríně: https://github.com/…xtension.php#…).

Z téhle metody je pak hezky patrné, jak se to nastavení parsuje: https://github.com/…/Helpers.php#L46.

No úložiště pro tyhle všechny cache může být libovolné – disk, nějaká memory databáze (například Redis)… Jen proxy třídy musí být vygenerované na disku.

Editoval Tharos (13. 10. 2015 9:38)

serten
Člen | 55
+
0
-

Tak jsem smazal všechnu cache co jsem mohl, vygeneroval jsem proxy třídy, provedl jsem znova validaci, ale nic nepomohlo. Neustále mi to vrací ten stejný výsledek při validaci.
Není nutné nastavovat ještě někde něco pro správné fungování? Už vážně nevím kde bych co změnil aby to fungovalo.

David Matějka
Moderator | 6445
+
+1
-

zkus jeste spustit

php www/index.php orm:clear-cache:metadata --flush

A jeste ukaz, jak teda nyni vypadaji ty entity

serten
Člen | 55
+
0
-

Tak díky všem za pomoc. Zkusil jsem ještě jednou projet postupy, co jste mi tu všichni radili a začalo to konečně fungovat. Asi jsem tam někde něco přehlídl nebo zapomněl, kvůli čemu to nejelo. Vše už tedy zvalidováno a funkční :-)

Ještě jednou díky