Kriterienabfragen mit JPA-Metamodell

1. Übersicht

In diesem Lernprogramm wird erläutert, wie Sie die statischen JPA-Metamodellklassen beim Schreiben von Kriterienabfragen im Ruhezustand verwenden.

Wir benötigen ein grundlegendes Verständnis der APIs für Kriterienabfragen im Ruhezustand. Weitere Informationen zu diesem Thema finden Sie bei Bedarf in unserem Lernprogramm zu Kriterienabfragen.

2. Warum das JPA-Metamodell?

Wenn wir eine Kriterienabfrage schreiben, müssen wir häufig auf Entitätsklassen und deren Attribute verweisen.

Eine Möglichkeit, dies zu tun, besteht darin, die Namen der Attribute als Zeichenfolgen anzugeben. Dies hat jedoch mehrere Nachteile.

Zum einen müssen wir die Namen der Entitätsattribute nachschlagen. Und falls ein Spaltenname später im Projektlebenszyklus geändert wird, müssen wir jede Abfrage, in der der Name verwendet wird, umgestalten.

Das JPA-Metamodell wurde von der Community eingeführt, um diese Nachteile zu vermeiden und statischen Zugriff auf die Metadaten der verwalteten Entitätsklassen zu ermöglichen.

3. Entitätsklasse

Betrachten wir ein Szenario, in dem wir ein Studentenportal-Verwaltungssystem für einen unserer Kunden erstellen und eine Anforderung zur Bereitstellung von Suchfunktionen für Studenten basierend auf ihrem Abschlussjahr gestellt wird.

Schauen wir uns zunächst unsere Schülerklasse an:

@Entity @Table(name = "students") public class Student { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; @Column(name = "grad_year") private int gradYear; // standard getters and setters }

4. Generieren von JPA-Metamodellklassen

Als Nächstes müssen wir die Metamodellklassen generieren. Zu diesem Zweck verwenden wir das von JBoss bereitgestellte Metamodellgenerator-Tool. JBoss ist nur eines der vielen verfügbaren Tools zum Generieren des Metamodells. Andere geeignete Tools sind EclipseLink, OpenJPA und DataNucleus.

Um das JBoss-Tool verwenden zu können, müssen wir die neueste Abhängigkeit in unsere Datei pom.xml einfügen. Das Tool generiert die Metamodellklassen, sobald wir den Befehl maven build auslösen:

 org.hibernate hibernate-jpamodelgen 5.3.7.Final 

Beachten Sie, dass wir den Ordner target / generierte Klassen zum Klassenpfad unserer IDE hinzufügen müssen , da die Klassen standardmäßig nur in diesem Ordner generiert werden.

5. Statische JPA-Metamodellklassen

Basierend auf der JPA-Spezifikation befindet sich eine generierte Klasse im selben Paket wie die entsprechende Entitätsklasse und hat denselben Namen mit einem zusätzlichen „_“ (Unterstrich) am Ende. Die für die Student- Klasse generierte Metamodellklasse lautet also Student_ und sieht ungefähr so aus:

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") @StaticMetamodel(Student.class) public abstract class Student_ { public static volatile SingularAttribute firstName; public static volatile SingularAttribute lastName; public static volatile SingularAttribute id; public static volatile SingularAttribute gradYear; public static final String FIRST_NAME = "firstName"; public static final String LAST_NAME = "lastName"; public static final String ID = "id"; public static final String GRAD_YEAR = "gradYear"; }

6. Verwenden von JPA-Metamodellklassen

Wir können die statischen Metamodellklassen genauso verwenden, wie wir die String- Verweise auf Attribute verwenden würden. Die Kriterienabfrage-API bietet überladene Methoden, die Zeichenfolgenreferenzen sowie Implementierungen der Attributschnittstelle akzeptieren .

Schauen wir uns die Kriterienabfrage an, mit der alle Studenten abgerufen werden , die 2015 ihren Abschluss gemacht haben:

//session set-up code CriteriaBuilder cb = session.getCriteriaBuilder(); CriteriaQuery criteriaQuery = cb.createQuery(Student.class); Root root = criteriaQuery.from(Student.class); criteriaQuery.select(root).where(cb.equal(root.get(Student_.gradYear), 2015)); Query query = session.createQuery(criteriaQuery); List results = query.getResultList();

Beachten Sie, wie wir die Student_.gradYear- Referenz anstelle des herkömmlichen Spaltennamens grad_year verwendet haben.

7. Fazit

In diesem kurzen Artikel haben wir gelernt, wie statische Metamodellklassen verwendet werden und warum sie möglicherweise der herkömmlichen Methode zur Verwendung von String- Referenzen vorgezogen werden, wie zuvor beschrieben.

Den Quellcode dieses Tutorials finden Sie auf Github.