Roman,

díky za príspevok, ale v tomto prípade filter použiť nejde. Ako ste správne poznamenali, filter sa dá použiť na celý Class alebo Collections, lenže ja mám many-to-one väzbu. A nemôžem mať množinu RECORD-ov v entite LOG, pretože hľadám práve také, ktoré ešte nemajú záznam v LOG.

Aj tak díky moc,
Rastislav "Bedo" Siekel



Roman Zakutny wrote:
Zdravim,

odhliadnuc od toho, ci Vase riesenie nie je zbytocne komplikovane, kedze nepoznam pozadie celeho problemu, sam som sa pred par mesiacmi taktiez stretol s absenciou moznosti pridat na ktorykolvek JOIN v dotaze vlastnu ON podmienku v Criteria API. O moznosti "with" som vedel, avsak HQL som sa pokial mozno chcel naozaj vyhnut. Na moje prekvapenie ta podpora tam bohuzial nebola (ak ak bola alebo uz je, budem velmi rad, ze ma niekto z tohoto omylu vyvedie:) Hibernate vsak ponuka riesenie a ja som ho vyuzil. Uz si detaily nepamatam, takze neviem presne povedat, aky to ma dopad na vykon. Nepouzival som ziadne FORMULA ani DISCRIMINATOR features, ale jednoduchy FILTER COLLECTIONS. Ide o to, ze ak chcete obmedzit nejaku podmnozinu dat, tak vo vysledku sa tato podmnozina typicky prejavi ako nejaka Collection v entite (vo Vasom pripade by to bolo Records v Log entite). Samotny dotaz je bez podmienok a vzhladom na to, ze vysledna Collection bude typicky LAZY natiahnuta, tak nasledujuce filtrovanie sa prevadza este v pamati bez pristupu do databazy, co oni oznacuju za velmi efektivny sposob. Ked potom pristupujete na jednotlive prvky kolekcie, tie uz splnaju Vami zadane kriteria. Takze taky workaround na ON podmienku...

Doporucujem si pozriet velmi jednoduchy priklad:
http://www.javalobby.org/java/forums/t43955.html

Na moj problem som si s tym bez problemov vystacil a nemusel som pouzit HQL. Chapem, ze pre komplikovane podmienky napriec roznymi entitami v dotaze toto pouzitie nemusi byt jednoduche, ba dokonca nemozne...

S pozdravom Roman.

On Wed, 16 Sep 2009 22:44:30 +0200, Lukas Barton <[email protected]> wrote:

Proc proste nenapisete:
select Record1 from Record1 where not exists(select Log.id from Log
where Log.id = Record1.id and Log.type = "TL")

Nemusite nic znasilnovat a je to i srozumitelnejsi.

On 9/16/09, Rastislav Siekel <[email protected]> wrote:
Ahojte,

nevedel by niekto poradiť ako dostanem v Hibernate podmienku do klauzuly
ON pre outer join?

Mám tabuľky záznamov - napr. RECORD1, RECORD2, ... a jednu tabuľku logov
- napr. LOG , kde si poznačím, ktoré záznamy a akého typu už boli
spracované.
Na úvod hľadám záznamy, ktoré ešte neboli vôbec spracované a preto v
tabuľke LOG nie sú. Typ záznamu hľadám napr. 'TL' a tie sú v tabuľke
RECORD1.


Potrebujem vygenerovať asi takýto SELECT:
*select RECORD1.*
from LOG
    right outer join RECORD1 on (**LOG.TYPE= 'TL' and
**RECORD1.ID=**LOG.ID**)
where LOG.ID is null
*

Hibernate som najprv znásilnil cez <formula>, aby mi to generoval, asi
takto:
*<class name="log" table="LOG" >
        <id name=... />

        <property name="record1_Id" column="RECORD1_ID" type=... />

        <many-to-one name="record1" column="RECORD1_ID" class=... />
            <formula>LOG_TYPE='TL' and RECORD1_ID</formula>
        </many-to-one>

       ...
</class>

*Toto fungovalo a všetko bolo v poriadku. Potom však prišla požiadavka
čítať záznamy z LOG-u a pre takéto mapovanie sa tá <formula> ocitla v
SELECT liste, čo samozrejme spôsobilo neplatné SQL.

Pokúšal som sa uvedené mapovanie zmeniť pomocou DISCRIMINATOR-a a nového
potomka triedy LOG (napr. logExt) nejako takto:
*<class name="log" table="LOG" >
        <id name=... />

         <discriminator column="LOG_TYPE" type="string" length="2" />

        <property name="record1_Id" column="RECORD1_ID" type=... />

        <subclass name="logExt" discriminator-value="TL">
** <many-to-one name="record1" column="RECORD1_ID" class=... />
**        </subclass>

       ...
</class>
*
Čo však vygenerovalo takýto SQL:
*select RECORD.ID, ...
from LOG
    right outer join RECORD on LOG.ID=RECORD.ID
where LOG.ID is null ** and **LOG.TYPE= 'TL'

*Čiže podmienka *LOG.TYPE= 'TL'* sa ocitla vo WHERE a nie v ON klauzule,
čo má samozrejme fatálny vplyv na výsledok, pretože ak LOG je null, tak
podmienka na LOG.TYPE je vždy FALSE a vráti sa prázdna množina.

Priateľ google napovedal, že Gavin 26.8.2003 tvrdil, že mapovanie
*<discriminator>* s atribútom *force="true"* prinesie tento
diskriminator do ON klauzuly - viď
https://forum.hibernate.org/viewtopic.php?f=1&t=934203&view=next
ale mne sa to takto nechová.


Teraz mi ostali asi 2 možnosti riešenia, ale ani jedna sa mi nepozdáva.

   1. Vytvoriť dve mapovania (trebárs ako predok a potomok), kde do
potomka dám uvedené hack-y typu <formula> a keď budem chcieť čítať
      záznamy z LOG-u, budem čítať predka.
   2. Použiť v HQL klauzulu WITH, ktorá dáva podmienku do ON klauzuly,
      ale musel by som zmeniť smer mapovania - RECORD by mal namapovaný
      LOG, čo je logicky zle, lebo entita RECORD nemá nič vedieť o tom,
      že si ju niekto loguje.


Neviete niekto ešte inú možnosť?

Rastislav "Bedo" Siekel

P.S. Hibernate 3.2.1.ga voči Oracle 10.

Odpovedet emailem