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, ...);