Tady myslím se vyjádřil Gavin King přesně: It cannot be done and it should not be done and you are trying to do a *Bad Thing*. ORM transparentní není a nebude. *See inline*
2013/4/29 Miroslav Paulfranc <paul...@seznam.cz> > Ahoj. > "* *tak by se kolekce permissions vrátila jen napůl plná" - to je to, co > potřebuju, nechci všechny permissions. > *Co by se mělo dít, když na entitě znovu zavoláš EntityManager.merge() nebo persist()? Mají se ty nedotažené permissions smazat?* > > SQL dotaz vrací přesně to, co potřebuju, jen není kolekce načtená. > *Jak sám píšeš, kolekce není načtená -> LazyInitializationException** * > > Chci "všechny Person, které mají Permission X" a "od nalezených Person > právě ty, s Permissions X" a v mém případě i Person bez Permissions. > > Dejme tomu budu chtít všechny uživatele bez oprávnění a zároveň uživatele, > kteří mají neplatná oprávnění , tj. > chci, aby se mi vrátil např. uživatel A, který nemá žádné oprávnění a > uživatel B s nějakými oprávněními, ale neplatnými. > > Díky za odpověd. > > > > > ---------- Původní zpráva ---------- > Od: Petr Janata <petrjan...@gmail.com> > Datum: 29. 4. 2013 > Předmět: Re: hibernate-critera s withClause > > Zdravím Mirku, > > problém je to prastarý (2005) a samotný tvůrce Gavin King se k němu > vyjádřil <https://forums.hibernate.org/viewtopic.php?t=944439>. > (Doporučuji dočíst thread do konce, kde je nádherný flame) > > Prakticky chceš asi dosáhnout tohoto: > Najdi všechny Person, které mají Permission X > A ZÁROVEŇ > vrať od nalezených Person všechny Permissions. > > To jedním joinem nepůjde, protože Permission musí být X a některé tím > pádem ve výsledku nebudou, což je v rozporu s druhou polovinou požadavku, > že se mají vrátit všechny. > Kdyby v třídě *JoinWalker *nebyla podmínka *&& ! oj.hasRestriction(), *tak > by se kolekce permissions vrátila jen napůl plná. > > Musíš to bohužel napsat explicitně: nejdřív zjistit, které Person entity > chceš a pak k nim dotáhnout všechny jejich permissions. > Zkusil bych: > > 1. 2 query, v první vybrat vhodné Person a pak k nim dotáhnout > permissions v druhé query > 2. použít > Criteria.ALIAS_TO_ENTITY_MAP<http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html_single/#querycriteria-associations>a > udělat si mapovací práci ručně v paměti > 3. mohlo by i fungovat FetchMode.SELECT, nebo subquery > > Petr Janata > > > 2013/4/29 Miroslav Paulfranc <paul...@seznam.cz> > > Zdravím všechny přítomné. > Narazil jsme v Hibernate (3.6 a 4.0) na problém týkající se Criteria API - > konkrétně jde o dotahování objektu s kolekcí. > > Situace je následující: > Mám dejme tomu třídu Person a ta má kolekci Permissions, která je v hbm > označena jako lazy loaded (lazy="true"). > > Pokud chci jedním SQL dotazem načíst osobu s kolekcí oprávnění, použiji: > > *DetachedCriteria criteria = DetachedCriteria.forClass(Person .class, > "person"); > criteria.createCriteria("permissions", "permission", > DetachedCriteria.LEFT_JOIN);* > > objekt třídy Person je potom natažen v rámci jednoho SQL dotazu včetně > Permissions. > > Pokud chci do podmínky k části join cokoliv přidat (např. omezit na platné > perm. kde validDateTo=null), použiju metodu > > DetachedCriteria<http://docs.jboss.org/hibernate/orm/3.6/javadocs/org/hibernate/criterion/DetachedCriteria.html> > *createCriteria<http://docs.jboss.org/hibernate/orm/3.6/javadocs/org/hibernate/criterion/DetachedCriteria.html#createCriteria%28java.lang.String,%20java.lang.String,%20int,%20org.hibernate.criterion.Criterion%29> > *(String<http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html?is-external=true> > associationPath, > String<http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html?is-external=true> > alias, > int joinType, > Criterion<http://docs.jboss.org/hibernate/orm/3.6/javadocs/org/hibernate/criterion/Criterion.html> > withClause) > > tj. > *criteria.createCriteria("permissions", "permission", > DetachedCriteria.LEFT_JOIN, nějakáPodmínka);* > > ,pak je generován SQL dotaz přesně tak, jak bych čekal > (dotaz z konkrétní aplikace*: left outer join dbo.zadost_data > zadostdata1_ on this_.zadost_id=zadostdata1_.zadost_id and ( > zadostdata1_.vt is not null )*) > , ale bohužel se nedotáhne kolekce permissions a pokus o přečtení končí > výjimkou *LazyInitializationException*.. > > Zkoušel jsem i nastavovat fetchMode ale bez úspěchu.. > > Ověřoval jsem na několika aplikacích a všude se stejným výsledkem. > > Metoda s parametrem Criterion byla přidána relativně "nedávno" (v 3.2. > myslím nebyla). > > Připadá mi, že pokud přidám withClause, ignoruje se potom fetch mode. > Tušíte prosím, jestli se dá přidat do join části nějakým jiným způsobem > další podmínka? > > Mimochodem; např. v Hibernate třídě *JoinWalker* jsou variace na podmínku > * > * > *if ( oj.getJoinType()==JoinType.LEFT_OUTER_JOIN && ! oj.hasRestriction()) { > //it must be a collection fetch > collectionPersisters[j] = collPersister; > collectionOwners[j] = oj.getOwner(associations); > j++; > }* > > kde *hasRestriction* indikuje použití podmínky withClause, tak nevím, > jestli to nemůže souviset s tímto problémem.. > > Předem děkuji za odpověd. > M.P. > > > > > > > > >