Hibernate discriminator v OUTER JOIN
Lukas Barton
lukas na cnawr.cz
Středa Září 16 22:44:30 CEST 2009
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 <siekel na prosoft.sk> 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.
>
Další informace o konferenci Konference