[Java/Hibernate] Query syntax

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

  • Swinnio
  • Registratie: Maart 2001
  • Laatst online: 20-02 07:52
Heb tot nu toe DB abstractie gebruik gemaakt van Torque. Maar in vergelijking met Hibernate zijn de ontwikkelingen en support minder dan bij Hibernate. Wilde dus eens proberen over te stappen. Het begin ging vrij soepel maar nu loop ik tegen wat dingen aan die in de documentatie niet zijn beschreven of juist zo uitgebreid dat ik door de bomen het bos niet meer zie.
Het volgende is het geval: net als Hibernate maakt Torque bij reverse engineering van een bestaande DB voor elke tabel een java klasse aan. Hierin zaten bv. de column names as static final strings opgeslagen. Dit is heel handig bij het formuleren van queries. Wanneer je bijvoorbeeld een Person tabel heeft met een PersonID en je wilde Person met ID=3 opvragen, kreeg je queries met criteriums in de vorm van
Java:
1
(Person.PersonID == 3).

In Hibernate moet je, voor zover ik het nu begrepen heb, zowel bij HQL als SQL queries steeds zelf weten welke colums zich in een tabel bevinden en hoe de tabel heet. Je krijgt dan bv.
Java:
1
session.createQuery("from Person")

met in het criterium:
Java:
1
Restrictions.eq("PersonID", 3).

Dit moet toch makkelijk kunnen? Ik moet toch bij het programmeren d.m.v. code completion kunnen zien welke velden Person heeft en daar mijn queries op kunnen baseren, zonder de structuur van buiten te kennen? Met andere woorden: ik wil niet steeds Strings "Person" en "PersonID" gebruiken, aangezien ik niet direct syntax controle heb en dus typefouten pas at runtime bemerk.

Een ander ding wat me uit de tutorial niet duidelijk wordt, is hoe de Manager klassen te ontwerpen. De tutorial maakt bv. voor het Object Event een EventManager klasse, waarbinnen dan specifieke functies (bv. create and store) geimplementeerd kunnen worden. Is dit de beste manier? M.a.w: moet ik voor elke Java klasse/DB Tabel een Manager implementeren? En hoe houd ik die dan gesynchroniseerd wanneer mijn Java Objecten opnieuw door Hibernate gegenereerd zijn?

Voor de volledigheid: ik gebruik Hibernate3.1.2. icm HibernateTools3.1.0beta4 en J2SDK1.5.0 (Geen J2EE dus!).

[ Voor 14% gewijzigd door Swinnio op 02-02-2006 09:56 ]

If the world wouldn't suck, we'd all fall off


  • momania
  • Registratie: Mei 2000
  • Laatst online: 08:47

momania

iPhone 30! Bam!

Het is goed om in je POJO's wat statics te implementeren per veld.
Java:
1
2
3
4
5
6
7
8
9
class Person {
  public static final String FLD_ID = "id";
  public static final String FLD_NAME = "name";

  public Long id = null;
  public String name = null;

  // getters/setters etc...
}

Dan kan je met criteria's aan de gang:
Java:
1
2
3
4
Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.eq(Person.FLD_ID, 3));

Person person = (Person)crit.uniqueResult();

Voor queries met echte criteria is dit een goed oplossing.

In dit geval zoek je alleen maar op de id van het object en dan kan je eigenlijk net zo goe het volgende gebruiken:
Java:
1
Person person = (Person)session.get(Person.class, 3);

Neem je whisky mee, is het te weinig... *zucht*


  • Swinnio
  • Registratie: Maart 2001
  • Laatst online: 20-02 07:52
Ok maar het is dus niet mogelijk die statics in mijn POJO automatisch via Hibernate te krijgen? Want het gebeurt regelmatig dat de DB waar ik mee werk kleine veranderingen ondergaat (bv. PersonID wordt Person_ID) en dan zou heb ik twee problemen:
1. Mijn extra code in de POJO's wordt overschreven wanneer ik ze opnieuw genereer (mbv. hbm2java).
2. Ik moet handmatig de statics corrigeren.

Inderdaard was mijn voorbeeld wat ongelukkig gekozen omdat ik een query met een ID gaf. Het was meer bedoeld voor queries die op andere velden zoeken uiteraard.

[ Voor 3% gewijzigd door Swinnio op 02-02-2006 10:44 ]

If the world wouldn't suck, we'd all fall off


Verwijderd

Probeer eens "from Person p where p.id =" ;)

  • Swinnio
  • Registratie: Maart 2001
  • Laatst online: 20-02 07:52
Verwijderd schreef op donderdag 02 februari 2006 @ 10:22:
Probeer eens "from Person p where p.id =" ;)
Of ik snap jouw grap niet of jij snapt mijn probleem niet ;)

If the world wouldn't suck, we'd all fall off


Verwijderd

Swinnio schreef op donderdag 02 februari 2006 @ 10:39:
Of ik snap jouw grap niet of jij snapt mijn probleem niet ;)
Dat laatste, beetje vluchtig gelezen. Je doet reverse engenering begrijp ik nu. Ik zou dat sowieso niet doen, daarvoor heb je nu juist een mapping. Je moet imo niet continu je domain layer opnieuw willen genereren, enkel je mappings aanpassen.

  • momania
  • Registratie: Mei 2000
  • Laatst online: 08:47

momania

iPhone 30! Bam!

Steeds je domain layer veranderen en dan reverse enginering zou ik idd ook niet doen.
Je komt dan idd niet alleen in de problemen bij queries, maar ook bij aanroep van getters en setters van je pojo's verderop in je applicatie.
Als iedere keer namen van attributen veranderen, blijf je refactoren.

Neem je whisky mee, is het te weinig... *zucht*


  • Swinnio
  • Registratie: Maart 2001
  • Laatst online: 20-02 07:52
momania schreef op donderdag 02 februari 2006 @ 11:14:
Steeds je domain layer veranderen en dan reverse enginering zou ik idd ook niet doen.
Je komt dan idd niet alleen in de problemen bij queries, maar ook bij aanroep van getters en setters van je pojo's verderop in je applicatie.
Als iedere keer namen van attributen veranderen, blijf je refactoren.
Het lijkt wel of je in de toekomst kan kijken :)
Loop nu tegen de volgende Hibernate meldingen aan:
code:
1
2
Feb 2, 2006 11:27:20 AM org.hibernate.property.BasicPropertyAccessor$BasicGetter get
SEVERE: IllegalArgumentException in class: de.imst.unet.database.hibernate.Segment, getter method of property: segmentId

Vreemd, een IllegalArgumentException in een
Java:
1
2
3
public long getSegmentId() {
        return this.segmentId;
}


/Edit:
Heb het probleem al gevonden: het ging om een many-to-one relatie, dus ik werkte zonder het te weten met een Set ipv. een Object :*)

Overigens is me een oplossing voor dit probleem ook nog niet helemaal duidelijk:
Een ander ding wat me uit de tutorial niet duidelijk wordt, is hoe de Manager klassen te ontwerpen. De tutorial maakt bv. voor het Object Event een EventManager klasse, waarbinnen dan specifieke functies (bv. create and store) geimplementeerd kunnen worden. Is dit de beste manier? M.a.w: moet ik voor elke Java klasse/DB Tabel een Manager implementeren? En hoe houd ik die dan gesynchroniseerd wanneer mijn Java Objecten opnieuw door Hibernate gegenereerd zijn?
Zijn dit misschien de *Home Objecten die Hibernate aan kan maken?

[ Voor 35% gewijzigd door Swinnio op 02-02-2006 13:45 ]

If the world wouldn't suck, we'd all fall off


  • Swinnio
  • Registratie: Maart 2001
  • Laatst online: 20-02 07:52
Niemand die iets zinnigs over de laatste vraag kan zeggen?

If the world wouldn't suck, we'd all fall off


  • momania
  • Registratie: Mei 2000
  • Laatst online: 08:47

momania

iPhone 30! Bam!

Swinnio schreef op zaterdag 04 februari 2006 @ 15:13:
Niemand die iets zinnigs over de laatste vraag kan zeggen?
Kijk eens naar een DAO pattern bijvoorbeeld. En eventueel naar en Factory pattern oid om die DAO's weer aan te maken in je controller laag.

Neem je whisky mee, is het te weinig... *zucht*


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
De attribuutnamen als string literals opnemen in Java source is niet zo handig. HQL queries kun je beter als "named queries" opnemen in de mapping files. Voordelen van named queries zijn dat ze tijdens opstarten al worden gecontroleerd (je ziet dus heel snel of iets stuk is), en het performt beter omdat de HQL niet iedere keer opnieuw hoeft te worden geparsed.

Als alternatief voor HQL en Criteria queries kun je ook Example Queries gebruiken. Het voordeel van Example Queries is dat je hiervoor gewoon de Java interface kunt gebruiken, geen String literals meer dus. Beide methodes voorkomen dat je losslingerende attribuutnamen hebt.

  • Swinnio
  • Registratie: Maart 2001
  • Laatst online: 20-02 07:52
momania schreef op zaterdag 04 februari 2006 @ 17:11:
[...]

Kijk eens naar een DAO pattern bijvoorbeeld. En eventueel naar en Factory pattern oid om die DAO's weer aan te maken in je controller laag.
Is DAO niet een J2EE pattern? Of heb ik gewoon nog niet goed begrepen en kan ik het in dit geval ook met J2SE gebruiken?
Zijn de Home objecten die door de hibernate tools aangemaakt kunnen worden trouwens bedoeld als DAO?

/update (voor degene die het interesseert): Generic DAO is inderdaad een goed optie, deze informatie op de Hibernite site is zeer behulpzaam geweest hierbij.

[ Voor 32% gewijzigd door Swinnio op 08-02-2006 08:56 ]

If the world wouldn't suck, we'd all fall off

Pagina: 1