Nyheder og Jobs

Querying with the New Java Persistence Criteria API: Dybt nørdet

Efter en kop kaffe kom jeg (Jesper) til en præsentation af query API’et i JPA 2. Ikke specielt metroseksuelt, men det er jeg jo nok heller ikke. Rummet var popfuldt, så det er åbanbart en socialt accepteret tilbøjelighed.

Criteria APIet er lidt som Hibernates criteria API , bare på generics-stereoider, så det er typsikkert hele vejen til udførelsen af query’et.

Det starter i CriteriaBuilder, som er en factory man får af EntityManageren.

Første gennemgang viste de voldsomt komplicerede strengbaserede API-typer. Det så ikke pænt ud og er ikke typesikkert. En længere diskussion i ekstpertgruppen gik på om man skulle bruge disse strenge, eller et typisikkert altenativ.

Man kan jo bruge klasse-literaler, men ikke literaler for felter og metoder. Vupi: Så kom der en metamodel, en abstrakt model over ens “persistence-unit”.

Metamodellen kan “browses” (itereres), men den dækker IKKE mapningen til det relationelle niveau. Og igen er det hele med typer på i generic-form.

Modellen kan bygges i hånden, men den skal hellere genereres statisk på en portabel måde, via en annotation processor, direkte fra ‘javac’.

Givet f.eks.

package domain;
@Entity
public class Person {
  @Id
  private long ssn;
  private string name;
  private int age;

  // public gettter/setter methods
  public String getName() {...}
}

kan provideren generere en metaklasse;

package domain;
import javax.persistence.metamodel.SingularAttribute;

@javax.persistence.metamodel.StaticMetamodel(domain.Person.class)

public class Person_ {
  public static volatile SingularAttribute<Person,Long> ssn;
  public static volatile SingularAttribute<Person,String> name;
  public static volatile SingularAttribute<Person,Integer> age;
}
Så kan man skrive queries på den typesikre måde:
CriteriaQuery<Account> c = cb.createQuery(Account.class);
Path<String> name = c.from(Account.class).get(Account_.owner).get(Person_.name);
c.where(cb.eq(name, "John Doe"));

Man kan nu også arbejde med tupler og constructorer, og det kan også opbygges med disse API’er.

Ikke med i JPA2.0: Updates of deletes – er ikke med endnu. QBE heller ikke. Metamodellen indholder ikke O/R mapningen.

Plus: JPA på stereoider. Aldrig mere bøvlede fejl under byg eller i produktion fordi man har ændret en detalje i modellen – eller færre. Enkelte ting, såsom  tupler, er dog ikke typesikre.

Minus: Overhead, måske på den onde måde. Jeg glæder mig til at se hvor slemme fejlbeskeder, kompileren giver når man  Nøden, der opgav efter 30 minutter. Tøsedreng.