Doctrine jednou vrací v poli proxy místo normálního objektu
- Oli
- Člen | 1215
Jedna entita se mě vrací jako proxy a ne jako normální entita. Je to entita, která je jako cizí klíč jiné entity.
Konkrétně mám entitu Photo
, která má property
GalleryId
. A jedna z fotek galerie má zase opačnou referenci,
že entita Gallery
má property mainPhoto
, která
ukazuje na objekt Photo. No a když si vytvořím dotaz:
public function grid($gallery)
{
return $this->repository->createQueryBuilder()
->select('p')
->from(Photo::class, 'p')
->where('p.galleryId = :gallery')
->setParameter('gallery', $gallery->id);
}
Tak v grido se to zpracovává touhle metodou. Problém je, že to vrátí všechny objekty jako instance Photo, jen tu jednu (na kterou ukazuje mainPhoto reference) se vrátí jako proxy.
Má na to vliv to že to je mainPhoto? Jde to nějak převést z proxy na normální objekt? Nějakej nápad jak to řešit?
- David Matějka
- Moderator | 6445
Ano, tohle je ocekavane chovani. V doctrine je jeden radek reprezentovany prave jednim objektem (diky identity mape)
Kdyz si nacet gallery, tak mainPhoto je lazy a proto se pro nej vytvorila proxy – ta obsahuje pouze identifikator a inicializuje se az kdyz je to potreba.
Kdyz si pak ten radek nacetl v jinem dotazu, tak doslo pouze k naplneni te proxy. Kdyby se vytvorila nova instance Photo, tak by zde byly dva objekty odkazujici na stejny zaznam.
Co konkretne se gridu nelibi na proxy?
- David Matějka
- Moderator | 6445
Jakou vyjimku to vyhodi? Kdyz se kouknu do dokumentace PropertyAccessor-u, ktery to pouziva, tak by to nejdriv melo pouzit getId metodu
- Oli
- Člen | 1215
No tuhle https://github.com/…peration.php#L165. Ale je pravda ze jsem ten accessor nikde explicitne nezapnul, musim se podivat jestli se zapnout musi nebo se zapina automaticky…
- David Matějka
- Moderator | 6445
hodilo by se vedet, ktera exception tam byla zachycena (je mimochodem chyba v grido, ze se ta exception nepredava jako previous)
- Oli
- Člen | 1215
Tak nakonec to s tou entitou vůbec nesouvisí. Tuhle chybu mě to dělá
jen při ajxovým hromadným mazání. Ono se to snaží vložit do
\Nette\Forms\Container
i tu neexistující smazanou položku.
Takže $primaryValue
je NULL a na tom to spadne.
Takže by to měl být spíš dotaz na @o5. Myslím, že to má něco společného i s tímhle: https://forum.nette.org/…id-pro-nette?p=12.
To mazání zpracovávám tadkhle:
public function handleOperations($operation, $id)
{
if ($id && is_array($id)) {
$row = implode(', ', $id);
foreach ($this->photosDao->findByIds($id) as $item) {
$this->deletePhoto($this->photosDao->findByObject($item->objectId));
}
$this->flashMessage("Process operation '$operation' for row with id: $row...", 'info');
} else {
$this->flashMessage($this->translator->translate('noRowsSelected'), 'error');
}
if ($this->presenter->isAjax()) {
$this->redrawControl('flashes');
}
$this->grid->reload();
}
Vypadá to, že ta metoda reload
nerefreshne grid… Ale proč?
Něco jsem přehlídnul?
ps. @DavidMatějka díky za tip s tou previous exception, to dost pomohlo :-)