Hibernate zoekopdracht mbv een collection

Pagina: 1
Acties:
  • 149 views sinds 30-01-2008
  • Reageer

  • ronaldmathies
  • Registratie: Juni 2001
  • Niet online
Ik krijg het niet voor elkaar om via een collection een zoekopdracht te doen. Om het probleem wat te verduidelijken heb ik het volgende voorbeeld:

Ik heb als voorbeeld even de volgende hibernate mappings in elkaar gezet om het probleem te verduidelijken:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<class name="nl.tmp.Person" table="person">
        <id name="id" column="ID" type="java.lang.Integer" unsaved-value="0">
            <generator class="increment"/>
        </id>
        <version name="version" column="VERSION" type="java.lang.Integer"/>
        <set name="addresses" cascade="all" inverse="true" lazy="false" outer-join="true">
            <key>
         <column name="addressId"/> 
            </key>
            <one-to-many
                class="nl.tmp.Address"/>
        </set>
</class>

<class name="nl.tmp.Address" table="address">
        <id name="id" column="ID" type="java.lang.Integer" unsaved-value="0">
            <generator class="increment"/>
        </id>
        <version name="version" column="VERSION" type="java.lang.Integer"/>
        <many-to-one name="state"
            class="nl.tmp.State"
            fetch="join">
            <column name="stateId"/>
        </many-to-one>
</class>

<class name="nl.tmp.State" table="state">
        <id name="id" column="ID" type="java.lang.Integer" unsaved-value="0">
            <generator class="increment"/>
        </id>
        <version name="version" column="VERSION" type="java.lang.Integer"/>
        <property
                name="name" 
                type="java.lang.String"
                not-null="true"
                length="2">
            <column name="name"/>
        </property> 
</class>


code:
1
2
3
4
5
6
7
8
9
10
11
12
public List getPersonsByState(State stateObject) {
        StringBuffer sql = new StringBuffer();
        sql.append("from Person as p ");
        sql.append("where p.addresses.state = :state";
                
        SessionFactory sessionFactory = getHibernateTemplate().getSessionFactory();
        Session session = sessionFactory.openSession();
        Query query = session.createQuery(sql.toString());
        query.setParameter("state", stateObject);
        List result = query.list();
        session.close();
}

Als ik de bovenstaande method uitvoer met een State object als argument dan krijg ik de volgende melding van hibernate:

illegal syntax near collection: adresses

Wat betekend deze melding en hoe moet ik dit probleem oplossen?
Ik wil dus eigenlijk alle personen hebben die in een bepaalde staat wonen, deze staat is echter geregistreerd bij het adres. En een
persoon kan één of meerdere adressen hebben.

3015 Wp-z 5360 Wp-nno op 2 x SMA-SB3600 TL-21, Warmtepomp: ERSC-VM2CR2 / PUHZ-SHW140 YHA, WTW Q350, EV Kia Ev6 GT-Line


  • whoami
  • Registratie: December 2000
  • Laatst online: 16:46
Volgens mij moet je gewoon gaan joinen; je Person dus aan je Adres object gaan joinen in je query, en dan ook nog eens aan je State, en dan de check doen op die property in State.

Maar ik weet niet of je dat wel kan doen, in jouw geval, aangezien je in je Adres class geen referentie hebt naar de Person tot wie dat adres behoort.

Een beetje zoals je met Sql zou doen dus...

https://fgheysels.github.io/


  • ronaldmathies
  • Registratie: Juni 2001
  • Niet online
Je bedoeld zoiets als:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 public List getPersonsByState(State stateObject) {
        StringBuffer sql = new StringBuffer();
        sql.append("from Person as p ");
        sql.append("join p.addresses as a ");
        sql.append("join a.state as s ");
        sql.append("where a = :state";
                
        SessionFactory sessionFactory = getHibernateTemplate().getSessionFactory();
        Session session = sessionFactory.openSession();
        Query query = session.createQuery(sql.toString());
        query.setParameter("state", stateObject);
        List result = query.list();
        session.close();
}

3015 Wp-z 5360 Wp-nno op 2 x SMA-SB3600 TL-21, Warmtepomp: ERSC-VM2CR2 / PUHZ-SHW140 YHA, WTW Q350, EV Kia Ev6 GT-Line


  • ronaldmathies
  • Registratie: Juni 2001
  • Niet online
Verek dat werkt inderdaad, waarbij deze regel

sql.append("join a.state as s ");

nog weggelaten kan worden. Zeer vermoeiend dit soort problemen, kost altijd maar een hoop tijd.

3015 Wp-z 5360 Wp-nno op 2 x SMA-SB3600 TL-21, Warmtepomp: ERSC-VM2CR2 / PUHZ-SHW140 YHA, WTW Q350, EV Kia Ev6 GT-Line


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

try:
code:
1
2
3
from Person as p where (
   from Address as address where address.state = :state
) in p.addresses

  • ronaldmathies
  • Registratie: Juni 2001
  • Niet online
code:
1
2
3
from Person as p where (
   from Address as address where address.state = :state
) in p.addresses


En stel dat het Person object ook een name property heeft, hoe gaat de query dan worden want ik denk niet dat het onderstaande dan nog goed is:

code:
1
2
3
4
from Person as p where (
   from Address as address where address.state = :state
) in p.addresses
and p.name = :name

3015 Wp-z 5360 Wp-nno op 2 x SMA-SB3600 TL-21, Warmtepomp: ERSC-VM2CR2 / PUHZ-SHW140 YHA, WTW Q350, EV Kia Ev6 GT-Line


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

ronaldmathies schreef op vrijdag 05 mei 2006 @ 16:23:
code:
1
2
3
from Person as p where (
   from Address as address where address.state = :state
) in p.addresses


En stel dat het Person object ook een name property heeft, hoe gaat de query dan worden want ik denk niet dat het onderstaande dan nog goed is:
Mijn kennis van HQL moet ook nodig opgefrist worden. Maar volgens mij wordt er gewoon een choicepoint op de stack gezet bij (from Address as address where address.state=:state) met daarin alle combinaties van addressen die in een bepaalde state liggen. Daarna word dan de 1e address gekozen en dat zal dan het resultaat zijn van die ( from address ..... ) query. En van die address kan weer bekeken worden of die in de p.addressen voorkomt.

Vervolgens kan aan die choicepoint gedraaid worden zodat je alle mogelijke combinaties van adressen in een bepaalde state zult doorlopen en alle goeie combinaties zult vinden van personen die aan die eisen voldoet.
code:
1
2
3
4
from Person as p where (
   from Address as address where address.state = :state
) in p.addresses
and p.name = :name
Waarom zou dit fout gaan?

Maar probeer hem eens. Ik ben erg nieuwschierig. Ik wil weten of mijn gedachtenkronkels kloppen.

[ Voor 6% gewijzigd door Alarmnummer op 05-05-2006 16:32 ]


Verwijderd

je kan dit ook zo doen, ik ben niet zo een HQL fan

SessionFactory sessionFactory = getHibernateTemplate().getSessionFactory();
Session session = sessionFactory.openSession();

Criteria criteria = session.createCriteria(Person.class);
criteria.createCriteria("addresses").add(Restrictions.eq("state", stateObject);

List list = criteria.list();

blijft je code ook nog mooi :*)

  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 03-02 20:14
je zou best via een hibernatecallback werken, zo hoef je niet wakker te liggen van het correct openen en afsluiten van sessies, heb je mooie translatie van de exceptions en doe je mee aan transacties...

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • ronaldmathies
  • Registratie: Juni 2001
  • Niet online
Ik gebruik hibernate in combinatie met Spring. Echter ik wil gewoon weten hoe HQL in elkaar steekt, en dit was één van die puntjes waarop ik vast liep. De manier om met de restrictions te werken is mij bekend. En dit werkt opzich vrij makkelijk. Maar soms is het noodzakelijk dat ik queries flexibel en gemakkelijk kan opbouwen a.h.v. opgegeven selectie criteria. Deze gaan vrij ver waardoor het gebruik van restrictions e.d. niet echt lekker werkt. Maar allemaal bedank voor de informatie. Het werkt inmiddels m.b.v. de joins.

3015 Wp-z 5360 Wp-nno op 2 x SMA-SB3600 TL-21, Warmtepomp: ERSC-VM2CR2 / PUHZ-SHW140 YHA, WTW Q350, EV Kia Ev6 GT-Line

Pagina: 1