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