Hibernate discriminator v OUTER JOIN

Rastislav Siekel siekel na prosoft.sk
Středa Září 16 17:49:08 CEST 2009


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ší část ---------------
HTML příloha byla odstraněna...
URL: <http://amaio.cz/pipermail/konference/attachments/20090916/1d95119d/attachment.htm>


Další informace o konferenci Konference