JPA 2.0 Criteria API How To

Einer der großen Neuerungen in JPA 2.0 war die (in den vorherigen Versionen sehr vermisste) Criteria API.

Die API ermöglicht es, Abfragen objektorientiert zu bauen. Diese Queries sind typsicher, somit kann der Compiler die Korrektheit der Abfrage überprüfen. Sie werden dynamisch zur Laufzeit gebaut.

In JPA 1.0 war dies nur mit Hilfe des zugrundliegenden Persistence Provider (z. B. Hibernate) möglich und dabei hat man am Standard “vorbei programmiert”.

Dieser Beitrag soll einen überblick über die Arbeit mit der Criteria API und JPA 2.0 geben.

Das ganze wird anhand einer unidirektionale 1->n Beziehung zwischen zwei Entitäten, Person und Adresse erläutert.
 

@Entity
@Table(name = "USER_TABLE")
public class Person {

...

 public Person() {
 super();
 }

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 public Long getId() {
 return id;
 }

 @OneToMany(cascade = CascadeType.PERSIST)
 @JoinColumn(name = "PERSON_FK")
 public Set<address> getAddresses() {
 return addresses;
 }

 public void setAddresses(Set<address> addresses) {
 this.addresses = addresses;
 }

...
}
@Entity
@Table(name = "ADRESS_TABLE")
public class Address {
 ...
 public Address() {
 super();
 }

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 public Long getId() {
 return id;
 }
 ...
}

Folgende Abfrage soll das Laden von Personen anhand des Vornamens zeigen:

entityManager = ...
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

CriteriaQuery<person> criteriaQuery = criteriaBuilder.createQuery(Person.class);

Root person = criteriaQuery.from(Person.class);

criteriaQuery.select(person).where(criteriaBuilder.equal(
 person.get(Person_.firstName), "Peter")).distinct(true);

person.join(Person_.addresses);

List<person> resultList = entityManager.createQuery(criteriaQuery).getResultList();

...

In Zeile 1 wird eine EntityManager geholt.

In Zeile 2 wird ein CriteriaBuilder Objekt ermittelt, dass als Factory für CriteriaQuery Instanzen dient. Das CriteriaQuery Objekt (Zeile 4) ist typisiert. Der generische Typ wird für die Ergebnismenge benutzt.

Ein Criteria Query Objekt definiert eine Abfrage über eine oder mehrere Entitäten. Das Root Objekt ist eine Entität über die die anderen Entitäten durch Navigation erreicht werden können. Das Pendant bei JPAQL, HQL oder SQL wäre die „From“-Klausel.

Metamodel

Die Where-Klausel (zeile 8) und der Join (Zeile 11) beinhalten ein ungewöhnliches Konstrukt Person_.firstName bzw. Person_.addresses um typsicher auf das Attribut firstName bzw. addresses von der Person zuzugreifen. Diese Attributen sind statische (public) Attribute aus der Person_ Klasse.  Person_ ist die entsprechende statische kanonische Metamodel Klasse der Person Entität und beschreibt die Metainformation der persistenten Klasse.

@StaticMetamodel(Person.class)
public abstract class Person_ {

 public static volatile SingularAttribute<person, Long> id;

 public static volatile SingularAttribute<person, String> lastName;

 public static volatile SingularAttribute<person, String> email;

 public static volatile SingularAttribute<person, String> firstName;

 public static volatile SetAttribute<person, Address> addresses;

}

Das Metamodel kann man sich generieren lassen( http://docs.jboss.org/hibernate/stable/jpamodelgen/reference/en-US/html_single/ ).

Short URL for this post: http://wp.me/p4nxik-fq
This entry was posted in Java Persistence and tagged , . Bookmark the permalink.