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.