Kdyby\Doctrine a __toString

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

Ahoj,
používám Kdyby\Doctrine (v3.1.2) a mám problém s metodou __toString. V entitě Pet mám:

	/**
	 * @var Parameter
	 * @ORM\ManyToOne(targetEntity="Parameter")
	 * @ORM\JoinColumn(name="parameter_id", referencedColumnName="id", nullable=true)
	 */
	private $parameter;

	// ...

	/**
	 * @return Parameter
	 */
	public function getParameter()
	{
		return $this->parameter; // vrací Kdyby\GeneratedProxy\__CG__\Model\Entities\Parameter
	}

v entitě Parameter mám:

	/**
	 * @var string
	 * @ORM\Column(type="string", length=500, nullable=false)
	 */
	private $name;

	// ...

	public function __toString()
	{
		return $this->name;
	}

a v latte to chci vypisovat takhle:

{$pet->getParameter()}

ale dostávám Method Kdyby\GeneratedProxy\__CG__\Model\Entities\Parameter::__toString() must not throw an exception.

Cache jsem mazala, nepomáhá. Nevím moc, co s tím – dá se nějak vynutit, aby ten getter nevracel proxy? Přijde mi, že problém je v metodě __toString té proxy, protože by měla volat parent::__toString, ale to se neděje… Nevíte někdo, v čem může být problém a jak to řešit?

Svaťa Šimara
Člen | 98
+
0
-

Problém je přesně ten, který popisuješ – pracuješ s proxy. Co s nima nepracovat?

Vlastně jde o to si všechny podřízené entity dotáhnout najednou napřed. Tj něco v tomto stylu…

$builder = $this->entityManager->createQueryBuilder();
$builder
	->from(Pet::class, 'p')
	->leftJoin('p.parameter', 'param')
	->select('p, param');
$query = $builder->getQuery();
$pets = $query->getResult();

Předpokládám, že v $this->entityManager bude EntityManager, dodatečné filtrování např. podle ID Pet můžeš udělat v rámci konfigurace query builderu.

Ano, je to víc psaní, ale na druhou stranu budeš máš dotazy pod kontrolou a pracuješ bez proxyn.

Tímto stylem se ale nahydratují entity, a ty jsou dost výkonově náročné. Doporučuji pro vypisování hydratovat do polí – $query->getArrayResult() nebo ještě efektivněji $query->getScalarResult(). Ano, pro vypisování sice nebudeš mít entity, refaktoring je složitější, ale máme výkon… no, něco za něco.

chikeet
Člen | 160
+
0
-

Tadáá, problém nalezen mezi klávesnicí a židlí. Mohly za to nějaké chybějící inversedBy v modelu a tím pádem se v modelu vyhazovala výjimka, která se projevovala takhle nepříliš intuitivně.

Poučení pro příště: když něco neklape v entitách, orm:validate-schema může napovědět.

@SvaťaŠimara díky, asi by to šlo, ale přijde mi to jako až moc psaní. Možná časem… :-)

Editoval chikeet (15. 2. 2017 13:05)