Donnerstag, 16. Februar 2012

Konstanten für JPA-NamedQueries

NamedQueries sind ein wichtiges Mittel zur JPA-Performance-Optimierung. Im letzten Workshop kam die Frage auf, wie man String-Literale für den Namen einer NamedQuery vermeidet:
@Entity
@NamedQueries({
@NamedQuery(
name = "findBenutzerByName",
query = "select b from Benutzer b where b.name=:name")
})
public class Benutzer {
...
}
Denn in einem Fall wie oben müsste derselbe String an den Stellen geschrieben werden, an denen die Abfrage aufgerufen werden soll:

EntityManager manager = ...;

TypedQuery<Benutzer> query =
manager.createNamedQuery(
"findBenutzerByName",
Benutzer.class);

query.setParameter("name", ...);

List<Benutzer> ergebnisse = query.getResultList();

Natürlich möchten wir dafür Konstanten verwenden – was auch bei Annotationen erlaubt ist. Die Frage ist nur, wo legen wir die Konstanten ab? Mein Vorschlag ist, dies direkt in der Entity zu tun:

@Entity
@NamedQueries({
@NamedQuery(
name = Benutzer.QUERY_FINDBYNAME,
query = "select b from Benutzer b where b.name=:"
+ Benutzer.QUERYPARAM_NAME)
})
public class Benutzer {

public static final String QUERY_FINDBYNAME = "findBenutzerByName";

public static final String QUERYPARAM_NAME = "name";

@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

@Column
private String name;

...
}
Dadurch wird an der Aufrufstelle klar, dass man passende Query-Strings und -Parameter verwendet:

TypedQuery<Benutzer> query =
manager.createNamedQuery(
Benutzer.QUERY_FINDBYNAME,
Benutzer.class);

query.setParameter(Benutzer.QUERYPARAM_NAME, ...);

1 Kommentar:

  1. Weitergehend muss man sich die Frage stellen, ob man nicht sogar den Aufruf der Query in die Entity-Klasse integrieren kann - als statische Methode. Dann entfällt das Veröffentlichen von Konstanten, was die Klasse sowieso unübersichtlich macht und ziemlich viel Arbeit verursacht.

    Stattdessen erhält man eine Java API für die Query, wobei die Parameter der Query die Parameter der Methode sind.

    War Eclipse verwendet, kann auf das Plug-In anqu-method benutzen, um den Code für die Methoden zu erzeugen. Der Entwickler muss sich dann nur um die Logik - nämlich die Query - kümmern.

    AntwortenLöschen