Bezbolestná integrace Doctrine 2 ORM do Nette – Kdyby/Doctrine

- akadlec
 - Člen | 1326
 
Počkej, jakto že nejde?
/**
 * @ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="author_type", type="string")
 * @ORM\DiscriminatorMap({
 * 		"guest"		= "Guest",
 * 		"system"	= "System",
 * 		"facebook"	= "Facebook",
 * 		"twitter"	= "Twitter",
 * 		"google"	= "Google",
 * 		"github"	= "Github"
 * })
 */
class Guest extends \IPub\Doctrine\Entity implements Comments\IAuthor
{
	//...
}
/**
 * @ORM\Entity
 */
class Comment extends \IPub\Doctrine\Entity implements IComment, Comments\IComment
{
	/**
	 * @var \IPub\Comments\Entities\IAuthor
	 * @writable
	 *
	 * @ORM\ManyToOne(targetEntity="IPub\CollectionsModule\Entities\Comments\Authors\Guest", cascade={"persist"})
	 * @ORM\JoinColumn(name="author_id", referencedColumnName="author_id", onDelete="CASCADE")
	 **/
	protected $author;
}
a načtou se mi jednotlivé entity podle sloupce. Nebo chceš něco jiného?

- mkoubik
 - Člen | 728
 
Climber007 napsal(a):
Vždycky chci buď rodiče nebo potomky s atributy rodiče.
Tak tohle samozřejmě jdem – to je klasická dědičnost. Máš třeba
třídu User, od které dědí třídy Customer a
Admin. Pak můžeš načíst objekt třídy Customer
včetně dat z třídy User, dokonce i objekt třídy
User, pokud není abstraktní, ale nemůžeš načíst objekt,
který (což jsem vyrozuměl že požaduješ) obsahuje data z
Customer a Admin zároveň (jaká třída by to
byla?).

- Climber007
 - Člen | 105
 
mkoubik napsal(a):
Climber007 napsal(a):
Vždycky chci buď rodiče nebo potomky s atributy rodiče.
Tak tohle samozřejmě jdem – to je klasická dědičnost. Máš třeba třídu
User, od které dědí třídyCustomeraAdmin. Pak můžeš načíst objekt třídyCustomervčetně dat z třídyUser, dokonce i objekt třídyUser, pokud není abstraktní, ale nemůžeš načíst objekt, který (což jsem vyrozuměl že požaduješ) obsahuje data zCustomeraAdminzároveň (jaká třída by to byla?).
Chci buď Customer nebo Admin s daty z
User. Problém je, že do toho diskriminatoru jde nacpat pouze
jedna z entit, nikoliv nějaká kolekce 2 a víc možných potomků.

- Climber007
 - Člen | 105
 
akadlec napsal(a):
Single table inheritance jak jsem ukazoval výše ne? Customer a Admin budou dědit od User a je to ne?
Jenže to mi nedovolí mít k jednomu User jednoho
Admin a zároveň Customer. Nebo snad jo? Zkoušel
jsem všechny možnosti a nic.

- mkoubik
 - Člen | 728
 
Ten admin a customer jsou dva různé objekty, takže jsou reprezentovány 2 řádky v tabulce. Pokud mají data z třídy User stejná, tak to v db prostě bude dvakrát. Pokud potřebuješ ta data v User sdílet mezi více objekty, tak to není dědičnost, ale kompozice.
Tzn, Customer a Admin by neměli od User dědit, ale místo toho dostat objekt třídy User např. v konstruktoru a plácnout ho do ManyToOne vazby.
Edit: Skus přesněji popsat čeho se snažíš dosáhnout. Všechno co se dá vyjádřit v php pomocí OOP, dědičnosti a kompozice se dá pomocí doctrine namapovat do db, opačně to jít nemusí. Napiš proto jak bys to chtěl řešit v php. Představ si že žádnou db nemáš a místo repository ukládáš/načítáš ty entity do/z asociativního pole podle id.
Editoval mkoubik (16. 5. 2014 14:27)

- Climber007
 - Člen | 105
 
mkoubik napsal(a):
Ten admin a customer jsou dva různé objekty, takže jsou reprezentovány 2 řádky v tabulce. Pokud mají data z třídy User stejná, tak to v db prostě bude dvakrát. Pokud potřebuješ ta data v User sdílet mezi více objekty, tak to není dědičnost, ale kompozice.
Tzn, Customer a Admin by neměli od User dědit, ale místo toho dostat objekt třídy User např. v konstruktoru a plácnout ho do ManyToOne vazby.
Díky moc za objasnění, přesně to jsem myslel! Potom už mi to došlo, že to dědičnost není a musím to řešit jinak.
Edit: Už to mám pomocí bidirectional OneToOne, kde vazba „potomků“
(Customer, Admin) k „rodiči“ (User)
je EAGER a obráceně je LAZY. Mám jednoduše potřebu uchovávat k více
uživatelským rolím další informace než k obyčejnému User,
kde jsou jen ta nejdůležitější data (username, pass, fullname). KDyž
pracuji s „potomky“, chci mít přístup k těm datům nahoře, ale
obráceně budu data tahat jen v minimu případů (proto LAZY). Snad je to tak
optimální řešení.
Editoval Climber007 (16. 5. 2014 14:33)

- sasule
 - Člen | 18
 
Ahoj,
měl bych tu drobný problém s cachováním do memcache.
Mám dva weby na jednom serveru, nastavil jsem cachování dle návodu:
doctrine:
    metadataCache: memcache(@memcache.client)
    queryCache: memcache(@memcache.client)
    resultCache: memcache(@memcache.client)
    hydrationCache: memcache(@memcache.client)
services:
    memcache.client:
        class: Memcache()
        setup:
            - addserver(localhost, 11211)
V obou webech používám objekt Sasule\Entities\User, který
ale v případě jednom má závislost na Sasule\Entities\Bank a
ve druhém ne. Podotýkám, že weby jsou na sobě nezávislé, každý má svou
databázi, jen běží na jednom fyzickém stroji.
První web spustím, vše OK, když poté spustím druhý, dostávám
výjimku:
Kdyby\Doctrine\MissingClassException, která říká, že
Sasule\Entities\Bank nebylo nalezeno (ani nemohlo, ve druhém webu
prostě není).
Tož, přemýšlím, co s tím? Protože předpokládám, že stejně se to bude chovat i kdekoli jinde.
Neexistuje třeba nějaké nastavení pro Memcache, kde by se vynutil nějaký „namespace“ pro cachovaná data?
Díky za případné rady.

- Climber007
 - Člen | 105
 
akadlec napsal(a):
@Filip Procházka: Díky tohle již funguje. K původní save metodě sem si přidal saveAll která provede save a flushne celý EM
Sice je to už dlouho, ale potřeboval bych jen potvrdit. Jestli není jiný
řešení:
Pokud mám One-To-One a potřebuji ukládat i změny v té druhé
entitě, je vhodný v service třídě s předaným DAO volat metodu
saveAll() namísto save():
public function saveAll(\App\Entities\IdentifiedEntity $entity)
{
    return $this->dao->getEntityManager()->flush();
}
Je to nejlepší řešení nebo je lepší sahat přímo na EM a
persist() a flush() metody? Nevadí, že budu tohle
používat pořád namísto save()? Kde by mohli v takovém
případě nastat problémy?
Díky moc!
PS: Sorry, ale příště už to půjde přes help.kdyby.org ;-)
Editoval Climber007 (31. 5. 2014 17:50)

- Tomáš Votruba
 - Moderator | 1114
 
Predej si rovnou entity manager a na nem volej flush(). Nema smysl jej nekam schovavat.

- Climber007
 - Člen | 105
 
Filip Procházka napsal(a):
Četl, ale lehce jsi to změnil od poslední návštěvy někdy v dubnu. Teď už je mi to jasný. Díky!

- Filip Procházka
 - Moderator | 4668
 
Další otázky prosím zakládejte jako samostatná témata na novém fóru help.kdyby.org. Díky!